Bug Summary

File:src/switch_log.c
Location:line 175, column 17
Description:The result of the '<<' expression is undefined

Annotated Source Code

1/*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18 *
19 * The Initial Developer of the Original Code is
20 * Anthony Minessale II <anthm@freeswitch.org>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Anthony Minessale II <anthm@freeswitch.org>
27 *
28 *
29 * switch_log.c -- Logging
30 *
31 */
32
33#include <switch.h>
34#include "private/switch_core_pvt.h"
35
36static const char *LEVELS[] = {
37 "CONSOLE",
38 "ALERT",
39 "CRIT",
40 "ERR",
41 "WARNING",
42 "NOTICE",
43 "INFO",
44 "DEBUG",
45 NULL((void*)0)
46};
47
48struct switch_log_binding {
49 switch_log_function_t function;
50 switch_log_level_t level;
51 int is_console;
52 struct switch_log_binding *next;
53};
54
55typedef struct switch_log_binding switch_log_binding_t;
56
57static switch_memory_pool_t *LOG_POOL = NULL((void*)0);
58static switch_log_binding_t *BINDINGS = NULL((void*)0);
59static switch_mutex_t *BINDLOCK = NULL((void*)0);
60static switch_queue_t *LOG_QUEUE = NULL((void*)0);
61#ifdef SWITCH_LOG_RECYCLE
62static switch_queue_t *LOG_RECYCLE_QUEUE = NULL((void*)0);
63#endif
64static int8_t THREAD_RUNNING = 0;
65static uint8_t MAX_LEVEL = 0;
66static int mods_loaded = 0;
67static int console_mods_loaded = 0;
68static switch_bool_t COLORIZE = SWITCH_FALSE;
69
70#ifdef WIN32
71static HANDLE hStdout;
72static WORD wOldColorAttrs;
73static CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
74
75static WORD
76#else
77static const char *
78#endif
79
80
81
82
83 COLORS[] =
84 { SWITCH_SEQ_DEFAULT_COLOR"\033[" "m", SWITCH_SEQ_FRED"\033[" "31" "m", SWITCH_SEQ_FRED"\033[" "31" "m", SWITCH_SEQ_FRED"\033[" "31" "m", SWITCH_SEQ_FMAGEN"\033[" "35" "m", SWITCH_SEQ_FCYAN"\033[" "36" "m", SWITCH_SEQ_FGREEN"\033[" "32" "m",
85SWITCH_SEQ_FYELLOW"\033[" "33" "m" };
86
87
88static switch_log_node_t *switch_log_node_alloc()
89{
90 switch_log_node_t *node = NULL((void*)0);
91#ifdef SWITCH_LOG_RECYCLE
92 void *pop = NULL((void*)0);
93
94 if (switch_queue_trypop(LOG_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) {
95 node = (switch_log_node_t *) pop;
96 } else {
97#endif
98 node = malloc(sizeof(*node));
99 switch_assert(node)((node) ? (void) (0) : __assert_fail ("node", "src/switch_log.c"
, 99, __PRETTY_FUNCTION__))
;
100#ifdef SWITCH_LOG_RECYCLE
101 }
102#endif
103 return node;
104}
105
106SWITCH_DECLARE(switch_log_node_t *)__attribute__((visibility("default"))) switch_log_node_t * switch_log_node_dup(const switch_log_node_t *node)
107{
108 switch_log_node_t *newnode = switch_log_node_alloc();
109
110 *newnode = *node;
111
112 if (!zstr(node->data)_zstr(node->data)) {
113 newnode->data = strdup(node->data)(__extension__ (__builtin_constant_p (node->data) &&
((size_t)(const void *)((node->data) + 1) - (size_t)(const
void *)(node->data) == 1) ? (((const char *) (node->data
))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({
size_t __len = strlen (node->data) + 1; char *__retval = (
char *) malloc (__len); if (__retval != ((void*)0)) __retval =
(char *) memcpy (__retval, node->data, __len); __retval; }
)) : __strdup (node->data)))
;
114 switch_assert(node->data)((node->data) ? (void) (0) : __assert_fail ("node->data"
, "src/switch_log.c", 114, __PRETTY_FUNCTION__))
;
115 }
116
117 if (!zstr(node->userdata)_zstr(node->userdata)) {
118 newnode->userdata = strdup(node->userdata)(__extension__ (__builtin_constant_p (node->userdata) &&
((size_t)(const void *)((node->userdata) + 1) - (size_t)(
const void *)(node->userdata) == 1) ? (((const char *) (node
->userdata))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t
) 1) : ({ size_t __len = strlen (node->userdata) + 1; char
*__retval = (char *) malloc (__len); if (__retval != ((void*
)0)) __retval = (char *) memcpy (__retval, node->userdata,
__len); __retval; })) : __strdup (node->userdata)))
;
119 switch_assert(node->userdata)((node->userdata) ? (void) (0) : __assert_fail ("node->userdata"
, "src/switch_log.c", 119, __PRETTY_FUNCTION__))
;
120 }
121
122 return newnode;
123}
124
125SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_log_node_free(switch_log_node_t **pnode)
126{
127 switch_log_node_t *node;
128
129 if (!pnode) {
130 return;
131 }
132
133 node = *pnode;
134
135 if (node) {
136 switch_safe_free(node->userdata)if (node->userdata) {free(node->userdata);node->userdata
=((void*)0);}
;
137 switch_safe_free(node->data)if (node->data) {free(node->data);node->data=((void*
)0);}
;
138#ifdef SWITCH_LOG_RECYCLE
139 if (switch_queue_trypush(LOG_RECYCLE_QUEUE, node) != SWITCH_STATUS_SUCCESS) {
140 free(node);
141 }
142#else
143 free(node);
144#endif
145 }
146 *pnode = NULL((void*)0);
147}
148
149SWITCH_DECLARE(const char *)__attribute__((visibility("default"))) const char * switch_log_level2str(switch_log_level_t level)
150{
151 if (level > SWITCH_LOG_DEBUG) {
152 level = SWITCH_LOG_DEBUG;
153 }
154 return LEVELS[level];
155}
156
157SWITCH_DECLARE(uint32_t)__attribute__((visibility("default"))) uint32_t switch_log_str2mask(const char *str)
158{
159 int argc = 0, x = 0;
160 char *argv[10] = { 0 };
161 uint32_t mask = 0;
162 char *p = strdup(str)(__extension__ (__builtin_constant_p (str) && ((size_t
)(const void *)((str) + 1) - (size_t)(const void *)(str) == 1
) ? (((const char *) (str))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (str) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, str, __len); __retval
; })) : __strdup (str)))
;
163 switch_log_level_t level;
164
165 switch_assert(p)((p) ? (void) (0) : __assert_fail ("p", "src/switch_log.c", 165
, __PRETTY_FUNCTION__))
;
166
167 if ((argc = switch_separate_string(p, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
1
Assuming 'argc' is non-zero
2
Taking true branch
168 for (x = 0; x < argc && argv[x]; x++) {
3
Loop condition is true. Entering loop body
169 if (!strcasecmp(argv[x], "all")) {
4
Taking false branch
170 mask = 0xFF;
171 break;
172 } else {
173 level = switch_log_str2level(argv[x]);
174 if (level != SWITCH_LOG_INVALID) {
5
Taking true branch
175 mask |= (1 << level);
6
The result of the '<<' expression is undefined
176 }
177 }
178 }
179 }
180
181 free(p);
182
183 return mask;
184}
185
186SWITCH_DECLARE(switch_log_level_t)__attribute__((visibility("default"))) switch_log_level_t switch_log_str2level(const char *str)
187{
188 int x = 0;
189 switch_log_level_t level = SWITCH_LOG_INVALID;
190
191 if (switch_is_number(str)) {
192 x = atoi(str);
193
194 if (x > SWITCH_LOG_INVALID) {
195 return SWITCH_LOG_INVALID - 1;
196 } else if (x < 0) {
197 return 0;
198 } else {
199 return x;
200 }
201 }
202
203
204 for (x = 0;; x++) {
205 if (!LEVELS[x]) {
206 break;
207 }
208
209 if (!strcasecmp(LEVELS[x], str)) {
210 level = (switch_log_level_t) x;
211 break;
212 }
213 }
214
215 return level;
216}
217
218SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_log_unbind_logger(switch_log_function_t function)
219{
220 switch_log_binding_t *ptr = NULL((void*)0), *last = NULL((void*)0);
221 switch_status_t status = SWITCH_STATUS_FALSE;
222
223 switch_mutex_lock(BINDLOCK);
224 for (ptr = BINDINGS; ptr; ptr = ptr->next) {
225 if (ptr->function == function) {
226 if (last) {
227 last->next = ptr->next;
228 } else {
229 BINDINGS = ptr->next;
230 }
231 status = SWITCH_STATUS_SUCCESS;
232 mods_loaded--;
233 if (ptr->is_console) {
234 console_mods_loaded--;
235 }
236 break;
237 }
238 last = ptr;
239 }
240 switch_mutex_unlock(BINDLOCK);
241
242 return status;
243}
244
245SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_log_bind_logger(switch_log_function_t function, switch_log_level_t level, switch_bool_t is_console)
246{
247 switch_log_binding_t *binding = NULL((void*)0), *ptr = NULL((void*)0);
248 switch_assert(function != NULL)((function != ((void*)0)) ? (void) (0) : __assert_fail ("function != ((void*)0)"
, "src/switch_log.c", 248, __PRETTY_FUNCTION__))
;
249
250 if (!(binding = switch_core_alloc(LOG_POOL, sizeof(*binding))switch_core_perform_alloc(LOG_POOL, sizeof(*binding), "src/switch_log.c"
, (const char *)__func__, 250)
)) {
251 return SWITCH_STATUS_MEMERR;
252 }
253
254 if ((uint8_t) level > MAX_LEVEL) {
255 MAX_LEVEL = level;
256 }
257
258 binding->function = function;
259 binding->level = level;
260 binding->is_console = is_console;
261
262 switch_mutex_lock(BINDLOCK);
263 for (ptr = BINDINGS; ptr && ptr->next; ptr = ptr->next);
264
265 if (ptr) {
266 ptr->next = binding;
267 } else {
268 BINDINGS = binding;
269 }
270 if (is_console) {
271 console_mods_loaded++;
272 }
273 mods_loaded++;
274 switch_mutex_unlock(BINDLOCK);
275
276 return SWITCH_STATUS_SUCCESS;
277}
278
279static switch_thread_t *thread;
280
281static void *SWITCH_THREAD_FUNC log_thread(switch_thread_t *t, void *obj)
282{
283
284 if (!obj) {
285 obj = NULL((void*)0);
286 }
287 THREAD_RUNNING = 1;
288
289 while (THREAD_RUNNING == 1) {
290 void *pop = NULL((void*)0);
291 switch_log_node_t *node = NULL((void*)0);
292 switch_log_binding_t *binding;
293
294 if (switch_queue_pop(LOG_QUEUE, &pop) != SWITCH_STATUS_SUCCESS) {
295 break;
296 }
297
298 if (!pop) {
299 THREAD_RUNNING = -1;
300 break;
301 }
302
303 node = (switch_log_node_t *) pop;
304 switch_mutex_lock(BINDLOCK);
305 for (binding = BINDINGS; binding; binding = binding->next) {
306 if (binding->level >= node->level) {
307 binding->function(node, node->level);
308 }
309 }
310 switch_mutex_unlock(BINDLOCK);
311
312 switch_log_node_free(&node);
313
314 }
315
316 THREAD_RUNNING = 0;
317 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_log.c", (const char *)__func__
, 317, ((void*)0)
, SWITCH_LOG_CONSOLE, "Logger Ended.\n");
318 return NULL((void*)0);
319}
320
321SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_log_printf(switch_text_channel_t channel, const char *file, const char *func, int line,
322 const char *userdata, switch_log_level_t level, const char *fmt, ...)
323{
324 va_list ap;
325
326 va_start(ap, fmt)__builtin_va_start(ap, fmt);
327 switch_log_vprintf(channel, file, func, line, userdata, level, fmt, ap);
328 va_end(ap)__builtin_va_end(ap);
329}
330
331#define do_mods(LOG_QUEUE && THREAD_RUNNING) (LOG_QUEUE && THREAD_RUNNING)
332SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_log_vprintf(switch_text_channel_t channel, const char *file, const char *func, int line,
333 const char *userdata, switch_log_level_t level, const char *fmt, va_list ap)
334{
335 char *data = NULL((void*)0);
336 char *new_fmt = NULL((void*)0);
337 int ret = 0;
338 FILE *handle;
339 const char *filep = (file ? switch_cut_path(file) : "");
340 const char *funcp = (func ? func : "");
341 char *content = NULL((void*)0);
342 switch_time_t now = switch_micro_time_now();
343 uint32_t len;
344#ifdef SWITCH_FUNC_IN_LOG
345 const char *extra_fmt = "%s [%s] %s:%d %s()%c%s";
346#else
347 const char *extra_fmt = "%s [%s] %s:%d%c%s";
348#endif
349 switch_log_level_t limit_level = runtime.hard_log_level;
350 switch_log_level_t special_level = SWITCH_LOG_UNINIT;
351
352 if (channel == SWITCH_CHANNEL_ID_SESSION && userdata) {
353 switch_core_session_t *session = (switch_core_session_t *) userdata;
354 special_level = session->loglevel;
355 if (limit_level < session->loglevel) {
356 limit_level = session->loglevel;
357 }
358 }
359
360 if (level > 100) {
361 if ((uint32_t) (level - 100) > runtime.debug_level) {
362 return;
363 }
364
365 level = 1;
366 }
367
368 if (level > limit_level) {
369 return;
370 }
371
372 switch_assert(level < SWITCH_LOG_INVALID)((level < SWITCH_LOG_INVALID) ? (void) (0) : __assert_fail
("level < SWITCH_LOG_INVALID", "src/switch_log.c", 372, __PRETTY_FUNCTION__
))
;
373
374 handle = switch_core_data_channel(channel);
375
376 if (channel != SWITCH_CHANNEL_ID_LOG_CLEAN) {
377 char date[80] = "";
378 //switch_size_t retsize;
379 switch_time_exp_t tm;
380
381 switch_time_exp_lt(&tm, now);
382 switch_snprintf(date, sizeof(date), "%0.4d-%0.2d-%0.2d %0.2d:%0.2d:%0.2d.%0.6d",
383 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec);
384
385 //switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
386
387#ifdef SWITCH_FUNC_IN_LOG
388 len = (uint32_t) (strlen(extra_fmt) + strlen(date) + strlen(filep) + 32 + strlen(funcp) + strlen(fmt));
389#else
390 len = (uint32_t) (strlen(extra_fmt) + strlen(date) + strlen(filep) + 32 + strlen(fmt));
391#endif
392 new_fmt = malloc(len + 1);
393 switch_assert(new_fmt)((new_fmt) ? (void) (0) : __assert_fail ("new_fmt", "src/switch_log.c"
, 393, __PRETTY_FUNCTION__))
;
394#ifdef SWITCH_FUNC_IN_LOG
395 switch_snprintf(new_fmt, len, extra_fmt, date, switch_log_level2str(level), filep, line, funcp, 128, fmt);
396#else
397 switch_snprintf(new_fmt, len, extra_fmt, date, switch_log_level2str(level), filep, line, 128, fmt);
398#endif
399
400 fmt = new_fmt;
401 }
402
403 ret = switch_vasprintf(&data, fmt, ap);
404
405 if (ret == -1) {
406 fprintf(stderrstderr, "Memory Error\n");
407 goto end;
408 }
409
410 if (channel == SWITCH_CHANNEL_ID_LOG_CLEAN) {
411 content = data;
412 } else {
413 if ((content = strchr(data, 128)(__extension__ (__builtin_constant_p (128) && !__builtin_constant_p
(data) && (128) == '\0' ? (char *) __rawmemchr (data
, 128) : __builtin_strchr (data, 128)))
)) {
414 *content = ' ';
415 }
416 }
417
418 if (channel == SWITCH_CHANNEL_ID_EVENT) {
419 switch_event_t *event;
420 if (switch_event_running() == SWITCH_STATUS_SUCCESS && switch_event_create(&event, SWITCH_EVENT_LOG)switch_event_create_subclass_detailed("src/switch_log.c", (const
char * )(const char *)__func__, 420, &event, SWITCH_EVENT_LOG
, ((void*)0))
== SWITCH_STATUS_SUCCESS) {
421 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Log-Data", data);
422 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Log-File", filep);
423 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Log-Function", funcp);
424 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Line", "%d", line);
425 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Level", "%d", (int) level);
426 if (!zstr(userdata)_zstr(userdata)) {
427 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "User-Data", userdata);
428 }
429 switch_event_fire(&event)switch_event_fire_detailed("src/switch_log.c", (const char * )
(const char *)__func__, 429, &event, ((void*)0))
;
430 data = NULL((void*)0);
431 }
432
433 goto end;
434 }
435
436 if (console_mods_loaded == 0 || !do_mods(LOG_QUEUE && THREAD_RUNNING)) {
437 if (handle) {
438 int aok = 1;
439#ifndef WIN32
440
441 fd_set can_write;
442 int fd;
443 struct timeval to;
444
445 fd = fileno(handle);
446 memset(&to, 0, sizeof(to));
447 FD_ZERO(&can_write)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq"
: "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) /
sizeof (__fd_mask)), "1" (&((&can_write)->fds_bits
)[0]) : "memory"); } while (0)
;
448 FD_SET(fd, &can_write)((void) (((&can_write)->fds_bits)[((fd) / (8 * (int) sizeof
(__fd_mask)))] |= ((__fd_mask) 1 << ((fd) % (8 * (int)
sizeof (__fd_mask))))))
;
449 to.tv_sec = 0;
450 to.tv_usec = 100000;
451 if (select(fd + 1, NULL((void*)0), &can_write, NULL((void*)0), &to) > 0) {
452 aok = FD_ISSET(fd, &can_write)((((&can_write)->fds_bits)[((fd) / (8 * (int) sizeof (
__fd_mask)))] & ((__fd_mask) 1 << ((fd) % (8 * (int
) sizeof (__fd_mask))))) != 0)
;
453 } else {
454 aok = 0;
455 }
456#endif
457 if (aok) {
458 if (COLORIZE) {
459
460#ifdef WIN32
461 SetConsoleTextAttribute(hStdout, COLORS[level]);
462 WriteFile(hStdout, data, (DWORD) strlen(data), NULL((void*)0), NULL((void*)0));
463 SetConsoleTextAttribute(hStdout, wOldColorAttrs);
464#else
465 fprintf(handle, "%s%s%s", COLORS[level], data, SWITCH_SEQ_DEFAULT_COLOR"\033[" "m");
466#endif
467 } else {
468 fprintf(handle, "%s", data);
469 }
470 }
471 }
472 }
473
474 if (do_mods(LOG_QUEUE && THREAD_RUNNING) && level <= MAX_LEVEL) {
475 switch_log_node_t *node = switch_log_node_alloc();
476
477 node->data = data;
478 data = NULL((void*)0);
479 switch_set_string(node->file, filep)switch_copy_string(node->file, filep, sizeof(node->file
))
;
480 switch_set_string(node->func, funcp)switch_copy_string(node->func, funcp, sizeof(node->func
))
;
481 node->line = line;
482 node->level = level;
483 node->slevel = special_level;
484 node->content = content;
485 node->timestamp = now;
486 node->channel = channel;
487 if (channel == SWITCH_CHANNEL_ID_SESSION) {
488 switch_core_session_t *session = (switch_core_session_t *) userdata;
489 node->userdata = userdata ? strdup(switch_core_session_get_uuid(session))(__extension__ (__builtin_constant_p (switch_core_session_get_uuid
(session)) && ((size_t)(const void *)((switch_core_session_get_uuid
(session)) + 1) - (size_t)(const void *)(switch_core_session_get_uuid
(session)) == 1) ? (((const char *) (switch_core_session_get_uuid
(session)))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t
) 1) : ({ size_t __len = strlen (switch_core_session_get_uuid
(session)) + 1; char *__retval = (char *) malloc (__len); if (
__retval != ((void*)0)) __retval = (char *) memcpy (__retval,
switch_core_session_get_uuid(session), __len); __retval; }))
: __strdup (switch_core_session_get_uuid(session))))
: NULL((void*)0);
490 } else {
491 node->userdata = !zstr(userdata)_zstr(userdata) ? strdup(userdata)(__extension__ (__builtin_constant_p (userdata) && ((
size_t)(const void *)((userdata) + 1) - (size_t)(const void *
)(userdata) == 1) ? (((const char *) (userdata))[0] == '\0' ?
(char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len =
strlen (userdata) + 1; char *__retval = (char *) malloc (__len
); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval
, userdata, __len); __retval; })) : __strdup (userdata)))
: NULL((void*)0);
492 }
493
494 if (switch_queue_trypush(LOG_QUEUE, node) != SWITCH_STATUS_SUCCESS) {
495 switch_log_node_free(&node);
496 }
497 }
498
499 end:
500
501 switch_safe_free(data)if (data) {free(data);data=((void*)0);};
502 switch_safe_free(new_fmt)if (new_fmt) {free(new_fmt);new_fmt=((void*)0);};
503
504}
505
506SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_log_init(switch_memory_pool_t *pool, switch_bool_t colorize)
507{
508 switch_threadattr_t *thd_attr;;
509
510 switch_assert(pool != NULL)((pool != ((void*)0)) ? (void) (0) : __assert_fail ("pool != ((void*)0)"
, "src/switch_log.c", 510, __PRETTY_FUNCTION__))
;
511
512 LOG_POOL = pool;
513
514 switch_threadattr_create(&thd_attr, LOG_POOL);
515 switch_threadattr_detach_set(thd_attr, 1);
516
517
518 switch_queue_create(&LOG_QUEUE, SWITCH_CORE_QUEUE_LEN100000, LOG_POOL);
519#ifdef SWITCH_LOG_RECYCLE
520 switch_queue_create(&LOG_RECYCLE_QUEUE, SWITCH_CORE_QUEUE_LEN100000, LOG_POOL);
521#endif
522 switch_mutex_init(&BINDLOCK, SWITCH_MUTEX_NESTED0x1, LOG_POOL);
523 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024);
524 switch_thread_create(&thread, thd_attr, log_thread, NULL((void*)0), LOG_POOL);
525
526 while (!THREAD_RUNNING) {
527 switch_cond_next();
528 }
529
530 if (colorize) {
531#ifdef WIN32
532 hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
533 if (switch_core_get_console() == stdoutstdout && hStdout != INVALID_HANDLE_VALUE && GetConsoleScreenBufferInfo(hStdout, &csbiInfo)) {
534 wOldColorAttrs = csbiInfo.wAttributes;
535 COLORIZE = SWITCH_TRUE;
536 }
537#else
538 COLORIZE = SWITCH_TRUE;
539#endif
540 }
541
542
543 return SWITCH_STATUS_SUCCESS;
544}
545
546SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_core_memory_reclaim_logger(void)
547{
548#ifdef SWITCH_LOG_RECYCLE
549 void *pop;
550 int size = switch_queue_size(LOG_RECYCLE_QUEUE);
551 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session)SWITCH_CHANNEL_ID_SESSION, "src/switch_log.c", (const char *)
__func__, 551, (const char*)(session)
, SWITCH_LOG_CONSOLE, "Returning %d recycled log node(s) %d bytes\n", size,
552 (int) sizeof(switch_log_node_t) * size);
553 while (switch_queue_trypop(LOG_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) {
554 switch_log_node_free(&pop);
555 }
556#else
557 return;
558#endif
559
560}
561
562SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_log_shutdown(void)
563{
564 switch_status_t st;
565
566
567 switch_queue_push(LOG_QUEUE, NULL((void*)0));
568 while (THREAD_RUNNING) {
569 switch_cond_next();
570 }
571
572 switch_thread_join(&st, thread);
573
574 switch_core_memory_reclaim_logger();
575
576 return SWITCH_STATUS_SUCCESS;
577}
578
579
580/* For Emacs:
581 * Local Variables:
582 * mode:c
583 * indent-tabs-mode:t
584 * tab-width:4
585 * c-basic-offset:4
586 * End:
587 * For VIM:
588 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
589 */