rendered paste bodyIndex: main/logger.c
===================================================================
--- main/logger.c (revision 42010)
+++ main/logger.c (working copy)
@@ -124,10 +124,18 @@
const char *file;
int line;
const char *function;
- char *str;
+ struct ast_dynamic_str *buf;
AST_LIST_ENTRY(logmsg) list;
};
+static void logmsg_cache_cleanup(void *data);
+
+/*! \brief A per-thread cache of logmsg structs */
+AST_THREADSTORAGE_CUSTOM(logmsg_cache, logmsg_cache_init, logmsg_cache_cleanup);
+
+/*! Default buffer length for a logmsg */
+#define LOGMSG_INIT_LEN 80
+
static AST_LIST_HEAD_STATIC(logmsgs, logmsg);
static pthread_t logthread = AST_PTHREADT_NULL;
static ast_cond_t logcond;
@@ -631,7 +639,7 @@
AST_LIST_LOCK(&logchannels);
if (logfiles.event_log && logmsg->level == __LOG_EVENT) {
- fprintf(eventlog, "%s asterisk[%ld]: %s", logmsg->date, (long)getpid(), logmsg->str);
+ fprintf(eventlog, "%s asterisk[%ld]: %s", logmsg->date, (long)getpid(), logmsg->buf->str);
fflush(eventlog);
AST_LIST_UNLOCK(&logchannels);
return;
@@ -644,7 +652,7 @@
continue;
/* Check syslog channels */
if (chan->type == LOGTYPE_SYSLOG && (chan->logmask & (1 << logmsg->level))) {
- ast_log_vsyslog(logmsg->level, logmsg->file, logmsg->line, logmsg->function, logmsg->str);
+ ast_log_vsyslog(logmsg->level, logmsg->file, logmsg->line, logmsg->function, logmsg->buf->str);
/* Console channels */
} else if (chan->type == LOGTYPE_CONSOLE && (chan->logmask & (1 << logmsg->level))) {
char linestr[128];
@@ -664,7 +672,7 @@
term_color(tmp2, logmsg->file, COLOR_BRWHITE, 0, sizeof(tmp2)),
term_color(tmp3, linestr, COLOR_BRWHITE, 0, sizeof(tmp3)),
term_color(tmp4, logmsg->function, COLOR_BRWHITE, 0, sizeof(tmp4)),
- logmsg->str);
+ logmsg->buf->str);
/* Print out */
ast_console_puts_mutable(buf);
/* File channels */
@@ -677,8 +685,8 @@
/* Print out to the file */
res = fprintf(chan->fileptr, "[%s] %s[%ld] %s: %s",
- logmsg->date, levels[logmsg->level], (long)GETTID(), logmsg->file, logmsg->str);
- if (res <= 0 && !ast_strlen_zero(logmsg->str)) {
+ logmsg->date, levels[logmsg->level], (long)GETTID(), logmsg->file, logmsg->buf->str);
+ if (res <= 0 && !ast_strlen_zero(logmsg->buf->str)) {
fprintf(stderr, "**** Asterisk Logging Error: ***********\n");
if (errno == ENOMEM || errno == ENOSPC)
fprintf(stderr, "Asterisk logging error: Out of disk space, can't log to log file %s\n", chan->filename);
@@ -690,7 +698,7 @@
}
}
} else if (logmsg->level != __LOG_VERBOSE) {
- fputs(logmsg->str, stdout);
+ fputs(logmsg->buf->str, stdout);
}
AST_LIST_UNLOCK(&logchannels);
@@ -706,6 +714,56 @@
return;
}
+static void logmsg_cache_cleanup(void *data)
+{
+ struct logmsgs *logmsgs = data;
+ struct logmsg *logmsg;
+
+ while ((logmsg = AST_LIST_REMOVE_HEAD(logmsgs, list)))
+ free(logmsg);
+
+ free(logmsgs);
+}
+
+static void logmsg_free(struct logmsg *logmsg)
+{
+ struct logmsgs *logmsgs;
+
+ if ((logmsgs = ast_threadstorage_get(&logmsg_cache, sizeof(*logmsgs)))) {
+ AST_LIST_INSERT_HEAD(logmsgs, logmsg, list);
+ return;
+ }
+
+ free(logmsg->buf);
+ free(logmsg);
+}
+
+static struct logmsg *logmsg_new(void)
+{
+ struct logmsgs *logmsgs;
+ struct logmsg *logmsg;
+
+ if ((logmsgs = ast_threadstorage_get(&logmsg_cache, sizeof(*logmsgs)))) {
+ if ((logmsg = AST_LIST_REMOVE_HEAD(logmsgs, list))) {
+ struct ast_dynamic_str *buf = logmsg->buf;
+ memset(logmsg, 0, sizeof(*logmsg));
+ logmsg->buf = buf;
+ ast_dynamic_str_set(&logmsg->buf, 0, "%s", "");
+ return logmsg;
+ }
+ }
+
+ if (!(logmsg = ast_calloc(1, sizeof(*logmsg))))
+ return NULL;
+
+ if (!(logmsg->buf = ast_dynamic_str_create(LOGMSG_INIT_LEN))) {
+ free(logmsg);
+ return NULL;
+ }
+
+ return logmsg;
+}
+
/* Print a verbose message to the verbosers */
static void logger_print_verbose(struct logmsg *logmsg)
{
@@ -714,7 +772,7 @@
/* Iterate through the list of verbosers and pass them the log message string */
AST_LIST_LOCK(&verbosers);
AST_LIST_TRAVERSE(&verbosers, v, list)
- v->verboser(logmsg->str);
+ v->verboser(logmsg->buf->str);
AST_LIST_UNLOCK(&verbosers);
return;
@@ -749,9 +807,7 @@
else if (msg->type == LOGMSG_VERBOSE)
logger_print_verbose(msg);
- /* Free the data since we are done */
- free(msg->str);
- free(msg);
+ logmsg_free(msg);
}
}
@@ -875,7 +931,7 @@
return;
/* Create a new logging message */
- if (!(logmsg = ast_calloc(1, sizeof(*logmsg))))
+ if (!(logmsg = logmsg_new()))
return;
/* Set type to be normal */
@@ -899,12 +955,12 @@
/* If the build failed, then abort and free this structure */
if (res == AST_DYNSTR_BUILD_FAILED) {
- free(logmsg);
+ logmsg_free(logmsg);
return;
}
/* Copy string over */
- logmsg->str = ast_strdup(buf->str);
+ ast_dynamic_str_set(&logmsg->buf, 0, buf->str);
/* Add it to the list at the tail end, and prod the logging thread */
AST_LIST_LOCK(&logmsgs);
@@ -954,7 +1010,7 @@
if (!(buf = ast_dynamic_str_thread_get(&verbose_buf, VERBOSE_BUF_INIT_SIZE)))
return;
- if (!(logmsg = ast_calloc(1, sizeof(*logmsg))))
+ if (!(logmsg = logmsg_new()))
return;
if (ast_opt_timestamp) {
@@ -981,13 +1037,11 @@
/* If the build failed then we can drop this allocated message */
if (res == AST_DYNSTR_BUILD_FAILED) {
- free(logmsg);
+ logmsg_free(logmsg);
return;
}
- /* Duplicate it in the logging message */
- logmsg->str = ast_strdup(buf->str);
- ast_log(LOG_VERBOSE, "%s", buf->str);
+ ast_dynamic_str_set(&logmsg->buf, 0, buf->str);
/* Add to the list and poke the thread */
AST_LIST_LOCK(&logmsgs);