diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 29aed6c49f..5c7116dcdb 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -1472,6 +1472,11 @@ SWITCH_DECLARE(uint8_t) switch_core_session_compare(switch_core_session_t *a, sw SWITCH_DECLARE(switch_loadable_module_interface_t *) switch_loadable_module_create_module_interface(switch_memory_pool_t *pool, const char *name); SWITCH_DECLARE(void *) switch_loadable_module_create_interface(switch_loadable_module_interface_t *mod, switch_module_interface_name_t iname); SWITCH_DECLARE(switch_time_t) switch_timestamp_now(void); +SWITCH_DECLARE(void) switch_core_memory_reclaim(void); +SWITCH_DECLARE(void) switch_core_memory_reclaim_events(void); +SWITCH_DECLARE(void) switch_core_memory_reclaim_logger(void); +SWITCH_DECLARE(void) switch_core_memory_reclaim_all(void); + ///\} /*! diff --git a/src/include/switch_types.h b/src/include/switch_types.h index ed737e77fc..bed0669ac1 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -480,7 +480,6 @@ typedef enum { \enum switch_log_level_t \brief Log Level Enumeration
-    SWITCH_LOG_CONSOLE          - Console
 	SWITCH_LOG_DEBUG            - Debug
 	SWITCH_LOG_INFO             - Info
 	SWITCH_LOG_NOTICE           - Notice
@@ -488,11 +487,10 @@ typedef enum {
 	SWITCH_LOG_ERROR            - Error
 	SWITCH_LOG_CRIT             - Critical
 	SWITCH_LOG_ALERT            - Alert
-	SWITCH_LOG_EMERG            - Emergency
+	SWITCH_LOG_CONSOLE          - Console
 
*/ typedef enum { - SWITCH_LOG_CONSOLE = 8, SWITCH_LOG_DEBUG = 7, SWITCH_LOG_INFO = 6, SWITCH_LOG_NOTICE = 5, @@ -500,7 +498,7 @@ typedef enum { SWITCH_LOG_ERROR = 3, SWITCH_LOG_CRIT = 2, SWITCH_LOG_ALERT = 1, - SWITCH_LOG_EMERG = 0 + SWITCH_LOG_CONSOLE = 0 } switch_log_level_t; @@ -1009,7 +1007,8 @@ typedef enum { SCSC_SHUTDOWN, SCSC_CHECK_RUNNING, SCSC_LOGLEVEL, - SCSC_SPS + SCSC_SPS, + SCSC_RECLAIM } switch_session_ctl_t; typedef struct apr_pool_t switch_memory_pool_t; diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 106e28e64a..8af5eef69f 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -116,6 +116,8 @@ SWITCH_STANDARD_API(ctl_function) } else if (!strcasecmp(argv[0], "shutdown")) { arg = 0; switch_core_session_ctl(SCSC_SHUTDOWN, &arg); + } else if (!strcasecmp(argv[0], "reclaim_mem")) { + switch_core_session_ctl(SCSC_RECLAIM, &arg); } else if (!strcasecmp(argv[0], "loglevel")) { if (argc > 1) { if (*argv[1] > 47 && *argv[1] < 58) { diff --git a/src/switch_core.c b/src/switch_core.c index 693c01cb28..4e2a0c9b3f 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -405,6 +405,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(const char *console, switch_cor memset(&runtime, 0, sizeof(runtime)); switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); + runtime.hard_log_level = SWITCH_LOG_DEBUG; /* INIT APR and Create the pool context */ if (apr_initialize() != SWITCH_STATUS_SUCCESS) { @@ -565,10 +566,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(const char *console signal(SIGPIPE, handle_SIGPIPE); #endif #ifdef SIGPOLL - signal(SIGPIPE, handle_SIGPOLL); + signal(SIGPOLL, handle_SIGPOLL); #endif #ifdef SIGIO - signal(SIGPIPE, handle_SIGIO); + signal(SIGIO, handle_SIGIO); #endif #ifdef TRAP_BUS signal(SIGBUS, handle_SIGBUS); @@ -651,8 +652,8 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_ runtime.hard_log_level = *val; } - if (runtime.hard_log_level > SWITCH_LOG_CONSOLE) { - runtime.hard_log_level = SWITCH_LOG_CONSOLE; + if (runtime.hard_log_level > SWITCH_LOG_DEBUG) { + runtime.hard_log_level = SWITCH_LOG_DEBUG; } *val = runtime.hard_log_level; break; @@ -664,6 +665,11 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_ *val = runtime.sps_total; switch_mutex_unlock(runtime.throttle_mutex); break; + + case SCSC_RECLAIM: + switch_core_memory_reclaim_all(); + *val = 0; + break; } return 0; @@ -739,6 +745,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void) return SWITCH_STATUS_SUCCESS; } +SWITCH_DECLARE(void) switch_core_memory_reclaim_all(void) +{ + switch_core_memory_reclaim_logger(); + switch_core_memory_reclaim_events(); + switch_core_memory_reclaim(); +} /* For Emacs: * Local Variables: diff --git a/src/switch_core_memory.c b/src/switch_core_memory.c index 426737573f..25d2a8ccda 100644 --- a/src/switch_core_memory.c +++ b/src/switch_core_memory.c @@ -282,8 +282,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_destroy_memory_pool(switch_m printf("Free Pool %s %s:%d\n", file, func, line); #endif - switch_queue_push(memory_manager.pool_queue, *pool); - //apr_pool_destroy(*pool); + if (switch_queue_trypush(memory_manager.pool_queue, *pool) != SWITCH_STATUS_SUCCESS) { + apr_pool_destroy(*pool); + } *pool = NULL; @@ -319,6 +320,22 @@ SWITCH_DECLARE(void *) switch_core_alloc(switch_memory_pool_t *pool, switch_size } +SWITCH_DECLARE(void) switch_core_memory_reclaim(void) +{ + switch_memory_pool_t *pool; + void *pop = NULL; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Returning %d recycled memory pool(s)\n", + switch_queue_size(memory_manager.pool_recycle_queue) + switch_queue_size(memory_manager.pool_queue)); + + while (switch_queue_trypop(memory_manager.pool_recycle_queue, &pop) == SWITCH_STATUS_SUCCESS) { + pool = (switch_memory_pool_t *) pop; + if (!pool) { + break; + } + apr_pool_destroy(pool); + } +} + static void *SWITCH_THREAD_FUNC pool_thread(switch_thread_t * thread, void *obj) { void *pop = NULL; @@ -347,7 +364,9 @@ static void *SWITCH_THREAD_FUNC pool_thread(switch_thread_t * thread, void *obj) pool = (switch_memory_pool_t *) pop; apr_pool_clear(pool); - switch_queue_push(memory_manager.pool_recycle_queue, pool); + if (switch_queue_trypush(memory_manager.pool_recycle_queue, pool) != SWITCH_STATUS_SUCCESS) { + apr_pool_destroy(pool); + } pool = NULL; x--; } @@ -361,16 +380,7 @@ static void *SWITCH_THREAD_FUNC pool_thread(switch_thread_t * thread, void *obj) } done: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Returning %d recycled memory pool(s)\n", - switch_queue_size(memory_manager.pool_recycle_queue) + switch_queue_size(memory_manager.pool_queue)); - - while (switch_queue_trypop(memory_manager.pool_recycle_queue, &pop) == SWITCH_STATUS_SUCCESS) { - pool = (switch_memory_pool_t *) pop; - if (!pool) { - break; - } - apr_pool_destroy(pool); - } + switch_core_memory_reclaim(); while (switch_queue_trypop(memory_manager.pool_queue, &pop) == SWITCH_STATUS_SUCCESS) { pool = (switch_memory_pool_t *) pop; @@ -388,7 +398,7 @@ static void *SWITCH_THREAD_FUNC pool_thread(switch_thread_t * thread, void *obj) void switch_core_memory_stop(void) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Stopping memory pool queue.\n"); - switch_queue_push(memory_manager.pool_queue, NULL); + memory_manager.pool_thread_running = -1; while(memory_manager.pool_thread_running) { switch_yield(1000); } diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 7ba0b1181c..194f20a5bf 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -215,6 +215,9 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t * thread, } } + while (switch_queue_trypop(sql_manager.sql_queue, &pop) == SWITCH_STATUS_SUCCESS) { + free(pop); + } free(sqlbuf); return NULL; diff --git a/src/switch_event.c b/src/switch_event.c index 9dd63821a4..0b0910c0a8 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -363,10 +363,25 @@ SWITCH_DECLARE(switch_status_t) switch_event_reserve_subclass_detailed(char *own } +SWITCH_DECLARE(void) switch_core_memory_reclaim_events(void) +{ + void *pop; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Returning %d recycled event node(s) and %d recycled event header node(s)\n", + switch_queue_size(EVENT_RECYCLE_QUEUE),switch_queue_size(EVENT_HEADER_RECYCLE_QUEUE)); + + while (switch_queue_trypop(EVENT_HEADER_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { + free(pop); + } + while (switch_queue_trypop(EVENT_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { + free(pop); + } + +} + SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void) { int x = 0, last = 0; - void *pop; + if (THREAD_RUNNING > 0) { THREAD_RUNNING = -1; @@ -405,16 +420,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void) } switch_core_hash_destroy(&CUSTOM_HASH); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Returning %d recycled event node(s) and %d recycled event header node(s)\n", - switch_queue_size(EVENT_RECYCLE_QUEUE),switch_queue_size(EVENT_HEADER_RECYCLE_QUEUE)); - - - while (switch_queue_trypop(EVENT_HEADER_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { - free(pop); - } - while (switch_queue_trypop(EVENT_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { - free(pop); - } + switch_core_memory_reclaim_events(); return SWITCH_STATUS_SUCCESS; @@ -541,7 +547,9 @@ SWITCH_DECLARE(switch_status_t) switch_event_del_header(switch_event_t *event, c } FREE(hp->name); FREE(hp->value); - switch_queue_push(EVENT_HEADER_RECYCLE_QUEUE, hp); + if (switch_queue_trypush(EVENT_HEADER_RECYCLE_QUEUE, hp) != SWITCH_STATUS_SUCCESS) { + FREE(hp); + } status = SWITCH_STATUS_SUCCESS; break; } @@ -629,10 +637,14 @@ SWITCH_DECLARE(void) switch_event_destroy(switch_event_t **event) hp = hp->next; FREE(this->name); FREE(this->value); - switch_queue_push(EVENT_HEADER_RECYCLE_QUEUE, this); + if (switch_queue_trypush(EVENT_HEADER_RECYCLE_QUEUE, this) != SWITCH_STATUS_SUCCESS) { + FREE(this); + } } FREE(ep->body); - switch_queue_push(EVENT_RECYCLE_QUEUE, ep); + if (switch_queue_trypush(EVENT_RECYCLE_QUEUE, ep) != SWITCH_STATUS_SUCCESS) { + FREE(ep); + } } *event = NULL; } diff --git a/src/switch_log.c b/src/switch_log.c index 3fc9a09ef6..8a749bfd0a 100644 --- a/src/switch_log.c +++ b/src/switch_log.c @@ -34,7 +34,7 @@ struct switch_runtime runtime; static const char *LEVELS[] = { - "EMERG", + "CONSOLE", "ALERT", "CRIT", "ERR", @@ -42,7 +42,6 @@ static const char *LEVELS[] = { "NOTICE", "INFO", "DEBUG", - "CONSOLE", NULL }; @@ -64,6 +63,9 @@ static uint8_t MAX_LEVEL = 0; SWITCH_DECLARE(const char *) switch_log_level2str(switch_log_level_t level) { + if (level > SWITCH_LOG_DEBUG) { + level = SWITCH_LOG_DEBUG; + } return LEVELS[level]; } @@ -71,6 +73,7 @@ SWITCH_DECLARE(switch_log_level_t) switch_log_str2level(const char *str) { int x = 0; switch_log_level_t level = SWITCH_LOG_DEBUG; + for (x = 0;; x++) { if (!LEVELS[x]) { break; @@ -144,7 +147,9 @@ static void *SWITCH_THREAD_FUNC log_thread(switch_thread_t * thread, void *obj) switch_mutex_unlock(BINDLOCK); switch_safe_free(node->data); - switch_queue_push(LOG_RECYCLE_QUEUE, node); + if (switch_queue_trypush(LOG_RECYCLE_QUEUE, node) != SWITCH_STATUS_SUCCESS) { + free(node); + } } THREAD_RUNNING = 0; @@ -167,7 +172,7 @@ SWITCH_DECLARE(void) switch_log_printf(switch_text_channel_t channel, const char uint32_t len; const char *extra_fmt = "%s [%s] %s:%d %s()%c%s"; - if (level < runtime.hard_log_level) { + if (level > runtime.hard_log_level) { return; } @@ -185,7 +190,7 @@ SWITCH_DECLARE(void) switch_log_printf(switch_text_channel_t channel, const char len = (uint32_t) (strlen(extra_fmt) + strlen(date) + strlen(filep) + 32 + strlen(funcp) + strlen(fmt)); new_fmt = malloc(len + 1); - snprintf(new_fmt, len, extra_fmt, date, LEVELS[level], filep, line, funcp, 128, fmt); + snprintf(new_fmt, len, extra_fmt, date, switch_log_level2str(level), filep, line, funcp, 128, fmt); fmt = new_fmt; } @@ -235,7 +240,11 @@ SWITCH_DECLARE(void) switch_log_printf(switch_text_channel_t channel, const char node->level = level; node->content = content; node->timestamp = now; - switch_queue_push(LOG_QUEUE, node); + if (switch_queue_trypush(LOG_QUEUE, node) != SWITCH_STATUS_SUCCESS) { + free(node->data); + free(node); + node = NULL; + } } } } @@ -270,21 +279,25 @@ SWITCH_DECLARE(switch_status_t) switch_log_init(switch_memory_pool_t *pool) return SWITCH_STATUS_SUCCESS; } -SWITCH_DECLARE(switch_status_t) switch_log_shutdown(void) +SWITCH_DECLARE(void) switch_core_memory_reclaim_logger(void) { void *pop; - + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Returning %d recycled log node(s)\n", switch_queue_size(LOG_RECYCLE_QUEUE)); + while (switch_queue_trypop(LOG_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { + free(pop); + } +} + +SWITCH_DECLARE(switch_status_t) switch_log_shutdown(void) +{ + THREAD_RUNNING = -1; switch_queue_push(LOG_QUEUE, NULL); while (THREAD_RUNNING) { switch_yield(1000); } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Returning %d recycled log node(s)\n", switch_queue_size(LOG_RECYCLE_QUEUE)); - while (switch_queue_trypop(LOG_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { - free(pop); - } - + switch_core_memory_reclaim_logger(); + return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_xml.c b/src/switch_xml.c index f3fbb4c841..cac4078c73 100644 --- a/src/switch_xml.c +++ b/src/switch_xml.c @@ -57,7 +57,7 @@ #ifndef WIN32 #include #endif - +#undef HAVE_MMAP #ifdef HAVE_MMAP #include #ifdef __sun