diff --git a/src/include/switch_core.h b/src/include/switch_core.h index cf184a3220..0fa6dae535 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -393,7 +393,8 @@ SWITCH_DECLARE(unsigned int) switch_core_session_running(_In_ switch_core_sessio \return a void pointer to the allocated memory \note this memory never goes out of scope until the core is destroyed */ -SWITCH_DECLARE(void *) switch_core_permanent_alloc(_In_ switch_size_t memory); +SWITCH_DECLARE(void *) switch_core_perform_permanent_alloc(_In_ switch_size_t memory, _In_z_ const char *file, _In_z_ const char *func, _In_ int line); +#define switch_core_permanent_alloc(m) switch_core_perform_permanent_alloc(m, __FILE__, __SWITCH_FUNC__, __LINE__) /*! \brief Allocate memory directly from a memory pool @@ -401,8 +402,8 @@ SWITCH_DECLARE(void *) switch_core_permanent_alloc(_In_ switch_size_t memory); \param memory the number of bytes to allocate \return a void pointer to the allocated memory */ -SWITCH_DECLARE(void *) switch_core_alloc(_In_ switch_memory_pool_t *pool, _In_ switch_size_t memory); - +SWITCH_DECLARE(void *) switch_core_perform_alloc(_In_ switch_memory_pool_t *pool, _In_ switch_size_t memory, _In_z_ const char *file, _In_z_ const char *func, _In_ int line); +#define switch_core_alloc(p, m) switch_core_perform_alloc(p, m, __FILE__, __SWITCH_FUNC__, __LINE__) /*! \brief Allocate memory from a session's pool \param session the session to request memory from @@ -410,14 +411,17 @@ SWITCH_DECLARE(void *) switch_core_alloc(_In_ switch_memory_pool_t *pool, _In_ s \return a void pointer to the newly allocated memory \note the memory will be in scope as long as the session exists */ -_Ret_ SWITCH_DECLARE(void *) switch_core_session_alloc(_In_ switch_core_session_t *session, _In_ switch_size_t memory); +_Ret_ SWITCH_DECLARE(void *) switch_core_perform_session_alloc(_In_ switch_core_session_t *session, _In_ switch_size_t memory, const char *file, const char *func, int line); +#define switch_core_session_alloc(s, m) switch_core_perform_session_alloc(s, m, __FILE__, __SWITCH_FUNC__, __LINE__) + /*! \brief Copy a string using permanent memory allocation \param todup the string to duplicate \return a pointer to the newly duplicated string */ -SWITCH_DECLARE(char *) switch_core_permanent_strdup(_In_z_ const char *todup); +SWITCH_DECLARE(char *) switch_core_perform_permanent_strdup(_In_z_ const char *todup, _In_z_ const char *file, _In_z_ const char *func, _In_ int line); +#define switch_core_permanent_strdup(t) switch_core_perform_permanent_strdup(t, __FILE__, __SWITCH_FUNC__, __LINE__) /*! \brief Copy a string using memory allocation from a session's pool @@ -425,7 +429,8 @@ SWITCH_DECLARE(char *) switch_core_permanent_strdup(_In_z_ const char *todup); \param todup the string to duplicate \return a pointer to the newly duplicated string */ -SWITCH_DECLARE(char *) switch_core_session_strdup(_In_ switch_core_session_t *session, _In_z_ const char *todup); +SWITCH_DECLARE(char *) switch_core_perform_session_strdup(_In_ switch_core_session_t *session, _In_z_ const char *todup, _In_z_ const char *file, _In_z_ const char *func, _In_ int line); +#define switch_core_session_strdup(s, t) switch_core_perform_session_strdup(s, t, __FILE__, __SWITCH_FUNC__, __LINE__) /*! \brief Copy a string using memory allocation from a given pool @@ -433,7 +438,8 @@ SWITCH_DECLARE(char *) switch_core_session_strdup(_In_ switch_core_session_t *se \param todup the string to duplicate \return a pointer to the newly duplicated string */ -SWITCH_DECLARE(char *) switch_core_strdup(_In_ switch_memory_pool_t *pool, _In_z_ const char *todup); +SWITCH_DECLARE(char *) switch_core_perform_strdup(_In_ switch_memory_pool_t *pool, _In_z_ const char *todup, _In_z_ const char *file, _In_z_ const char *func, _In_ int line); +#define switch_core_strdup(p, t) switch_core_perform_strdup(p, t, __FILE__, __SWITCH_FUNC__, __LINE__) /*! \brief printf-style style printing routine. The data is output to a string allocated from the session diff --git a/src/switch_core_memory.c b/src/switch_core_memory.c index 1835d388b0..d2486b1c03 100644 --- a/src/switch_core_memory.c +++ b/src/switch_core_memory.c @@ -31,6 +31,10 @@ * switch_core_memory.c -- Main Core Library (memory management) * */ +//#define DEBUG_ALLOC +//#define DEBUG_ALLOC2 +//#define DESTROY_POOLS +//#define PER_POOL_LOCK #include #include "private/switch_core_pvt.h" @@ -54,7 +58,7 @@ SWITCH_DECLARE(switch_memory_pool_t *) switch_core_session_get_pool(switch_core_ /* **ONLY** alloc things with this function that **WILL NOT** outlive the session itself or expect an earth shattering KABOOM!*/ -SWITCH_DECLARE(void *) switch_core_session_alloc(switch_core_session_t *session, switch_size_t memory) +SWITCH_DECLARE(void *) switch_core_perform_session_alloc(switch_core_session_t *session, switch_size_t memory, const char *file, const char *func, int line) { void *ptr = NULL; switch_assert(session != NULL); @@ -65,7 +69,8 @@ SWITCH_DECLARE(void *) switch_core_session_alloc(switch_core_session_t *session, #endif #ifdef DEBUG_ALLOC - printf("Allocate %d\n", (int)memory); + if (memory > 500) + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Session Allocate %d\n", (int)memory); #endif ptr = apr_palloc(session->pool, memory); @@ -83,7 +88,7 @@ SWITCH_DECLARE(void *) switch_core_session_alloc(switch_core_session_t *session, /* **ONLY** alloc things with these functions that **WILL NOT** need to be freed *EVER* ie this is for *PERMANENT* memory allocation */ -SWITCH_DECLARE(void *) switch_core_permanent_alloc(switch_size_t memory) +SWITCH_DECLARE(void *) switch_core_perform_permanent_alloc(switch_size_t memory, const char *file, const char *func, int line) { void *ptr = NULL; switch_assert(memory_manager.memory_pool != NULL); @@ -93,7 +98,7 @@ SWITCH_DECLARE(void *) switch_core_permanent_alloc(switch_size_t memory) #endif #ifdef DEBUG_ALLOC - printf("Perm Allocate %d\n", (int)memory); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Perm Allocate %d\n", (int)memory); #endif ptr = apr_palloc(memory_manager.memory_pool, memory); @@ -108,7 +113,7 @@ SWITCH_DECLARE(void *) switch_core_permanent_alloc(switch_size_t memory) return ptr; } -SWITCH_DECLARE(char *) switch_core_permanent_strdup(const char *todup) +SWITCH_DECLARE(char *) switch_core_perform_permanent_strdup(const char *todup, const char *file, const char *func, int line) { char *duped = NULL; switch_size_t len; @@ -126,7 +131,7 @@ SWITCH_DECLARE(char *) switch_core_permanent_strdup(const char *todup) switch_assert(duped != NULL); #ifdef DEBUG_ALLOC - printf("Perm Allocate %d\n", (int)len); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Perm Allocate %d\n", (int)len); #endif #ifdef LOCK_MORE @@ -184,7 +189,7 @@ SWITCH_DECLARE(char *) switch_core_sprintf(switch_memory_pool_t *pool, const cha return result; } -SWITCH_DECLARE(char *) switch_core_session_strdup(switch_core_session_t *session, const char *todup) +SWITCH_DECLARE(char *) switch_core_perform_session_strdup(switch_core_session_t *session, const char *todup, const char *file, const char *func, int line) { char *duped = NULL; switch_size_t len; @@ -202,7 +207,8 @@ SWITCH_DECLARE(char *) switch_core_session_strdup(switch_core_session_t *session len = strlen(todup) + 1; #ifdef DEBUG_ALLOC - printf("Allocate %d\n", (int)len); + if (len > 500) + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Sess Strdup Allocate %d\n", (int)len); #endif duped = apr_pstrmemdup(session->pool, todup, len); @@ -216,7 +222,7 @@ SWITCH_DECLARE(char *) switch_core_session_strdup(switch_core_session_t *session return duped; } -SWITCH_DECLARE(char *) switch_core_strdup(switch_memory_pool_t *pool, const char *todup) +SWITCH_DECLARE(char *) switch_core_perform_strdup(switch_memory_pool_t *pool, const char *todup, const char *file, const char *func, int line) { char *duped = NULL; switch_size_t len; @@ -233,7 +239,8 @@ SWITCH_DECLARE(char *) switch_core_strdup(switch_memory_pool_t *pool, const char len = strlen(todup) + 1; #ifdef DEBUG_ALLOC - printf("Allocate %d\n", (int)len); + if (len > 500) + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "core strdup Allocate %d\n", (int)len); #endif duped = apr_pstrmemdup(pool, todup, len); @@ -294,7 +301,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_new_memory_pool(switch_memor #endif #ifdef DEBUG_ALLOC2 - printf("New Pool %s %s:%d\n", file, func, line); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "New Pool\n"); #endif tmp = switch_core_sprintf(*pool, "%s:%d", func, line); apr_pool_tag(*pool, tmp); @@ -311,7 +318,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_destroy_memory_pool(switch_m switch_assert(pool != NULL); #ifdef DEBUG_ALLOC2 - printf("Free Pool %s %s:%d\n", file, func, line); + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Free Pool\n"); #endif if (switch_queue_push(memory_manager.pool_queue, *pool) != SWITCH_STATUS_SUCCESS) { @@ -322,7 +329,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_destroy_memory_pool(switch_m return SWITCH_STATUS_SUCCESS; } -SWITCH_DECLARE(void *) switch_core_alloc(switch_memory_pool_t *pool, switch_size_t memory) +SWITCH_DECLARE(void *) switch_core_perform_alloc(switch_memory_pool_t *pool, switch_size_t memory, const char *file, const char *func, int line) { void *ptr = NULL; @@ -333,7 +340,8 @@ SWITCH_DECLARE(void *) switch_core_alloc(switch_memory_pool_t *pool, switch_size #endif #ifdef DEBUG_ALLOC - printf("Allocate %d\n", (int)memory); + if (memory > 500) + switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "Core Allocate %d\n", (int)memory); /*switch_assert(memory < 20000);*/ #endif diff --git a/src/switch_event.c b/src/switch_event.c index fd37212479..60e306da7d 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -34,7 +34,10 @@ #include #include +#define MAX_DISPATCH 20 +#define DISPATCH_QUEUE_LEN 1000 +static int SOFT_MAX_DISPATCH = 0; static char hostname[128] = ""; static char guess_ip_v4[80] = ""; static char guess_ip_v6[80] = ""; @@ -47,6 +50,7 @@ static switch_thread_cond_t *EVENT_QUEUE_CONDITIONAL = NULL; static switch_memory_pool_t *RUNTIME_POOL = NULL; static switch_memory_pool_t *THRUNTIME_POOL = NULL; static switch_queue_t *EVENT_QUEUE[3] = { 0, 0, 0 }; +static switch_queue_t *EVENT_DISPATCH_QUEUE[MAX_DISPATCH] = { 0 }; static int POOL_COUNT_MAX = SWITCH_CORE_QUEUE_LEN; static switch_hash_t *CUSTOM_HASH = NULL; @@ -54,6 +58,7 @@ static int THREAD_RUNNING = 0; static int EVENT_QUEUE_HAVEMORE = 0; static switch_queue_t *EVENT_RECYCLE_QUEUE = NULL; static switch_queue_t *EVENT_HEADER_RECYCLE_QUEUE = NULL; +static void launch_dispatch_threads(int max, int len, switch_memory_pool_t *pool); static char *my_dup (const char *s) { @@ -168,6 +173,33 @@ static int switch_events_match(switch_event_t *event, switch_event_node_t *node) return match; } +static void *SWITCH_THREAD_FUNC switch_event_dispatch_thread(switch_thread_t * thread, void *obj) +{ + switch_queue_t *queue = (switch_queue_t *) obj; + int THREAD_RUNNING = 1; + + while (THREAD_RUNNING == 1) { + void *pop = NULL; + switch_event_t *event = NULL; + + if (switch_queue_pop(queue, &pop) != SWITCH_STATUS_SUCCESS) { + break; + } + + if (!pop) { + break; + } + + event = (switch_event_t *) pop; + switch_event_deliver(&event); + } + + THREAD_RUNNING = 0; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Dispatch Ended.\n"); + return NULL; + +} + static void *SWITCH_THREAD_FUNC switch_event_thread(switch_thread_t * thread, void *obj) { switch_event_t *out_event = NULL; @@ -175,6 +207,7 @@ static void *SWITCH_THREAD_FUNC switch_event_thread(switch_thread_t * thread, vo switch_queue_t *queues[3] = { 0, 0, 0 }; void *pop; int i, len[3] = { 0, 0, 0 }; + int index = 0; switch_assert(thread != NULL); switch_assert(obj == NULL); @@ -199,7 +232,6 @@ static void *SWITCH_THREAD_FUNC switch_event_thread(switch_thread_t * thread, vo len[0] = switch_queue_size(EVENT_QUEUE[SWITCH_PRIORITY_HIGH]); any = len[1] + len[2] + len[0]; - if (!any) { /* lock on havemore so we are the only ones poking at it while we check it * see if we saw anything in the queues or have a check again flag @@ -236,11 +268,43 @@ static void *SWITCH_THREAD_FUNC switch_event_thread(switch_thread_t * thread, vo for (i = 0; i < 3; i++) { if (len[i]) { + queue = queues[i]; + while (queue) { if (switch_queue_trypop(queue, &pop) == SWITCH_STATUS_SUCCESS) { out_event = pop; - switch_event_deliver(&out_event); + + if (!pop) { + continue; + } + + retry: + + for (index = 0; index < SOFT_MAX_DISPATCH; index++) { + if (switch_queue_trypush(EVENT_DISPATCH_QUEUE[index], out_event) == SWITCH_STATUS_SUCCESS) { + out_event = NULL; + break; + } + } + + if (out_event) { + switch_yield(1000); + + if (SOFT_MAX_DISPATCH+1 < MAX_DISPATCH) { + launch_dispatch_threads(SOFT_MAX_DISPATCH+1, DISPATCH_QUEUE_LEN, RUNTIME_POOL); + } + + goto retry; + } + +#ifdef DEBUG_DISPATCH_QUEUES + printf ("SIZE "); + for (index = 0; index < SOFT_MAX_DISPATCH; index++) { + printf ("%d ", switch_queue_size(EVENT_DISPATCH_QUEUE[index])); + } + printf("\n"); +#endif } else { break; } @@ -356,7 +420,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void) if (THREAD_RUNNING > 0) { THREAD_RUNNING = -1; - /* lock on havemore to make sure he event thread, if currently running + /* lock on havemore to make sure the event thread, if currently running * doesn't check the HAVEMORE flag before we set it */ switch_mutex_lock(EVENT_QUEUE_HAVEMORE_MUTEX); @@ -380,7 +444,12 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void) switch_mutex_unlock(EVENT_QUEUE_HAVEMORE_MUTEX); } - while (x < 100 && THREAD_RUNNING) { + for(x = 0; x < SOFT_MAX_DISPATCH; x++) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Stopping dispatch queue %d\n", x); + switch_queue_trypush(EVENT_DISPATCH_QUEUE[x], NULL); + } + + while (x < 10000 && THREAD_RUNNING) { switch_yield(1000); if (THREAD_RUNNING == last) { x++; @@ -395,6 +464,35 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void) return SWITCH_STATUS_SUCCESS; } +static void launch_dispatch_threads(int max, int len, switch_memory_pool_t *pool) +{ + switch_thread_t *thread; + switch_threadattr_t *thd_attr;; + int index = 0; + + if (max > MAX_DISPATCH) { + return; + } + + if (max < SOFT_MAX_DISPATCH) { + return; + } + + for (index = SOFT_MAX_DISPATCH; index < max && index < MAX_DISPATCH; index++) { + if (EVENT_DISPATCH_QUEUE[index]) { + continue; + } + switch_queue_create(&EVENT_DISPATCH_QUEUE[index], len, pool); + switch_threadattr_create(&thd_attr, pool); + switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_threadattr_priority_increase(thd_attr); + switch_thread_create(&thread, thd_attr, switch_event_dispatch_thread, EVENT_DISPATCH_QUEUE[index], pool); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Create event dispatch thread %d\n", index); + } + + SOFT_MAX_DISPATCH = index; +} + SWITCH_DECLARE(switch_status_t) switch_event_init(switch_memory_pool_t *pool) { switch_thread_t *thread; @@ -413,6 +511,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_init(switch_memory_pool_t *pool) switch_queue_create(&EVENT_QUEUE[2], POOL_COUNT_MAX + 10, THRUNTIME_POOL); switch_queue_create(&EVENT_RECYCLE_QUEUE, 250000, THRUNTIME_POOL); switch_queue_create(&EVENT_HEADER_RECYCLE_QUEUE, 250000, THRUNTIME_POOL); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Activate Eventing Engine.\n"); switch_mutex_init(&BLOCK, SWITCH_MUTEX_NESTED, RUNTIME_POOL); @@ -422,6 +521,9 @@ SWITCH_DECLARE(switch_status_t) switch_event_init(switch_memory_pool_t *pool) switch_thread_cond_create(&EVENT_QUEUE_CONDITIONAL, RUNTIME_POOL); switch_core_hash_init(&CUSTOM_HASH, RUNTIME_POOL); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); + switch_threadattr_priority_increase(thd_attr); + + launch_dispatch_threads(1, DISPATCH_QUEUE_LEN, RUNTIME_POOL); switch_thread_create(&thread, thd_attr, switch_event_thread, NULL, RUNTIME_POOL); while (!THREAD_RUNNING) { @@ -902,7 +1004,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_fire_detailed(const char *file, con if (user_data) { (*event)->event_user_data = user_data; } - + switch_queue_push(EVENT_QUEUE[(*event)->priority], *event); /* lock on havemore to make sure he event thread, if currently running diff --git a/src/switch_log.c b/src/switch_log.c index ef45ca8725..e5cdb4bdcd 100644 --- a/src/switch_log.c +++ b/src/switch_log.c @@ -226,81 +226,90 @@ SWITCH_DECLARE(void) switch_log_printf(switch_text_channel_t channel, const char ret = switch_vasprintf(&data, fmt, ap); va_end(ap); + if (ret == -1) { fprintf(stderr, "Memory Error\n"); + goto end; + } + + if (channel == SWITCH_CHANNEL_ID_LOG_CLEAN) { + content = data; } else { - - if (channel == SWITCH_CHANNEL_ID_LOG_CLEAN) { - content = data; - } else { - if ((content = strchr(data, 128))) { - *content = ' '; - } - } - - if (channel == SWITCH_CHANNEL_ID_EVENT) { - switch_event_t *event; - if (switch_event_running() == SWITCH_STATUS_SUCCESS && switch_event_create(&event, SWITCH_EVENT_LOG) == SWITCH_STATUS_SUCCESS) { - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Data", "%s", data); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-File", "%s", filep); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Function", "%s", funcp); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Line", "%d", line); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Level", "%d", (int) level); - switch_event_fire(&event); - } - } else { - if (level == SWITCH_LOG_CONSOLE || !LOG_QUEUE || !THREAD_RUNNING) { - if (handle) { - int aok = 1; -#ifndef WIN32 - - fd_set can_write; - int fd; - struct timeval to; - - fd = fileno(handle); - memset(&to, 0, sizeof(to)); - FD_SET(fd, &can_write); - to.tv_sec = 0; - to.tv_usec = 5000; - if (select(fd+1, NULL, &can_write, NULL, &to) > 0) { - aok = FD_ISSET(fd, &can_write); - } else { - aok = 0; - } -#endif - if (aok) { - fprintf(handle, "%s", data); - } - } - free(data); - } else if (level <= MAX_LEVEL) { - switch_log_node_t *node; - void *pop = NULL; - - if (switch_queue_trypop(LOG_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { - node = (switch_log_node_t *) pop; - } else { - node = malloc(sizeof(*node)); - switch_assert(node); - } - - node->data = data; - switch_set_string(node->file, filep); - switch_set_string(node->func, funcp); - node->line = line; - node->level = level; - node->content = content; - node->timestamp = now; - if (switch_queue_trypush(LOG_QUEUE, node) != SWITCH_STATUS_SUCCESS) { - free(node->data); - free(node); - node = NULL; - } - } + if ((content = strchr(data, 128))) { + *content = ' '; } } + if (channel == SWITCH_CHANNEL_ID_EVENT) { + switch_event_t *event; + if (switch_event_running() == SWITCH_STATUS_SUCCESS && switch_event_create(&event, SWITCH_EVENT_LOG) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Data", "%s", data); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-File", "%s", filep); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Function", "%s", funcp); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Line", "%d", line); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Level", "%d", (int) level); + switch_event_fire(&event); + data = NULL; + } + + goto end; + } + + if (level == SWITCH_LOG_CONSOLE || !LOG_QUEUE || !THREAD_RUNNING) { + if (handle) { + int aok = 1; +#ifndef WIN32 + + fd_set can_write; + int fd; + struct timeval to; + + fd = fileno(handle); + memset(&to, 0, sizeof(to)); + FD_SET(fd, &can_write); + to.tv_sec = 0; + to.tv_usec = 5000; + if (select(fd+1, NULL, &can_write, NULL, &to) > 0) { + aok = FD_ISSET(fd, &can_write); + } else { + aok = 0; + } +#endif + if (aok) { + fprintf(handle, "%s", data); + } + } + } else if (level <= MAX_LEVEL) { + switch_log_node_t *node; + void *pop = NULL; + + if (switch_queue_trypop(LOG_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { + node = (switch_log_node_t *) pop; + } else { + node = malloc(sizeof(*node)); + switch_assert(node); + } + + node->data = data; + data = NULL; + switch_set_string(node->file, filep); + switch_set_string(node->func, funcp); + node->line = line; + node->level = level; + node->content = content; + node->timestamp = now; + if (switch_queue_trypush(LOG_QUEUE, node) != SWITCH_STATUS_SUCCESS) { + free(node->data); + if (switch_queue_trypush(LOG_RECYCLE_QUEUE, node) != SWITCH_STATUS_SUCCESS) { + free(node); + } + node = NULL; + } + } + + end: + + switch_safe_free(data); switch_safe_free(new_fmt); fflush(handle); }