From a885027ff1669b638314c36d01078369321d71a6 Mon Sep 17 00:00:00 2001 From: Davide Paro Date: Tue, 4 Jan 2022 18:20:35 +0100 Subject: [PATCH] Fixed thread race condition --- src/log.c | 183 +++++++++++++++++++++++------------------------------- src/log.h | 3 +- 2 files changed, 79 insertions(+), 107 deletions(-) diff --git a/src/log.c b/src/log.c index 12938e9..9128554 100644 --- a/src/log.c +++ b/src/log.c @@ -25,159 +25,132 @@ #define MAX_CALLBACKS 32 typedef struct { - log_LogFn fn; - void *udata; - int level; + log_LogFn fn; + void *udata; + int level; } Callback; static struct { - void *udata; - log_LockFn lock; - int level; - bool quiet; - Callback callbacks[MAX_CALLBACKS]; + void *udata; + log_LockFn lock; + int level; + bool quiet; + Callback callbacks[MAX_CALLBACKS]; } L = { - NULL, - NULL, - RXI_LOGC_DEFAULT_LEVEL, - false, - {0}, + NULL, NULL, RXI_LOGC_DEFAULT_LEVEL, false, {0}, }; +static const char *level_strings[] = {"[[DEBUG]]", "[[TRACE]]", "[[ INFO]]", + "[[ WARN]]", "[[ERROR]]", "[[FATAL]]"}; -static const char *level_strings[] = { - "[[DEBUG]]", "[[TRACE]]", "[[ INFO]]", "[[ WARN]]", "[[ERROR]]", "[[FATAL]]" -}; - - -static inline const char *get_level_string(int level) -{ +static inline const char *get_level_string(int level) { return level_strings[(level + 32) / 32]; } #ifdef LOG_USE_COLOR -static const char *level_colors[] = { - "\x1b[36m", "\x1b[94m", "\x1b[32m", "\x1b[33m", "\x1b[31m", "\x1b[35m" -}; +static const char *level_colors[] = {"\x1b[36m", "\x1b[94m", "\x1b[32m", + "\x1b[33m", "\x1b[31m", "\x1b[35m"}; -static inline const char *get_level_color(int level) -{ +static inline const char *get_level_color(int level) { return level_colors[(level + 32) / 32]; } #endif - - - - static void stdout_callback(log_Event *ev) { - char buf[16]; - buf[strftime(buf, sizeof(buf), "%H:%M:%S", ev->time)] = '\0'; + char buf[16]; + buf[strftime(buf, sizeof(buf), "%H:%M:%S", ev->time)] = '\0'; #ifdef LOG_USE_COLOR - fprintf( - ev->udata, "%s %s%-7s\x1b[0m \x1b[90m%s:%d:\x1b[0m ", - buf, get_level_color(ev->level), get_level_string(ev->level), - ev->file, ev->line); + fprintf(ev->udata, "%s %s%-7s\x1b[0m \x1b[90m%s:%d:\x1b[0m ", buf, + get_level_color(ev->level), get_level_string(ev->level), ev->file, + ev->line); #else - fprintf( - ev->udata, "%s %-7s %s:%d: ", - buf, get_level_string(ev->level), ev->file, ev->line); + fprintf(ev->udata, "%s %-7s %s:%d: ", buf, get_level_string(ev->level), + ev->file, ev->line); #endif - vfprintf(ev->udata, ev->fmt, ev->ap); - fprintf(ev->udata, "\n"); - fflush(ev->udata); + vfprintf(ev->udata, ev->fmt, ev->ap); + fprintf(ev->udata, "\n"); + fflush(ev->udata); } - static void file_callback(log_Event *ev) { - char buf[64]; - buf[strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", ev->time)] = '\0'; - fprintf( - ev->udata, "%s %-7s %s:%d: ", - buf, get_level_string(ev->level), ev->file, ev->line); - vfprintf(ev->udata, ev->fmt, ev->ap); - fprintf(ev->udata, "\n"); - fflush(ev->udata); + char buf[64]; + buf[strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", ev->time)] = '\0'; + fprintf(ev->udata, "%s %-7s %s:%d: ", buf, get_level_string(ev->level), + ev->file, ev->line); + vfprintf(ev->udata, ev->fmt, ev->ap); + fprintf(ev->udata, "\n"); + fflush(ev->udata); } - -static void lock(void) { - if (L.lock) { L.lock(true, L.udata); } +static void lock(void) { + if (L.lock) { + L.lock(true, L.udata); + } } - static void unlock(void) { - if (L.lock) { L.lock(false, L.udata); } + if (L.lock) { + L.lock(false, L.udata); + } } - void log_set_lock(log_LockFn fn, void *udata) { - L.lock = fn; - L.udata = udata; + L.lock = fn; + L.udata = udata; } +void log_set_level(int level) { L.level = level; } -void log_set_level(int level) { - L.level = level; -} - - -void log_set_quiet(bool enable) { - L.quiet = enable; -} - +void log_set_quiet(bool enable) { L.quiet = enable; } int log_add_callback(log_LogFn fn, void *udata, int level) { - for (int i = 0; i < MAX_CALLBACKS; i++) { - if (!L.callbacks[i].fn) { - L.callbacks[i] = (Callback) { fn, udata, level }; - return 0; + for (int i = 0; i < MAX_CALLBACKS; i++) { + if (!L.callbacks[i].fn) { + L.callbacks[i] = (Callback){fn, udata, level}; + return 0; + } } - } - return -1; + return -1; } - int log_add_fp(FILE *fp, int level) { - return log_add_callback(file_callback, fp, level); + return log_add_callback(file_callback, fp, level); } - static void init_event(log_Event *ev, void *udata) { - if (!ev->time) { - time_t t = time(NULL); - ev->time = localtime(&t); - } - ev->udata = udata; + if (!ev->time) { + time_t t = time(NULL); + localtime_r(&t, &ev->time_buf); + } + ev->udata = udata; } - void log_log(int level, const char *file, int line, const char *fmt, ...) { - log_Event ev = { - .fmt = fmt, - .file = file, - .line = line, - .level = level, - }; + log_Event ev = { + .fmt = fmt, + .file = file, + .line = line, + .level = level, + }; - lock(); + lock(); - if (!L.quiet && level >= L.level) { - init_event(&ev, stderr); - va_start(ev.ap, fmt); - stdout_callback(&ev); - va_end(ev.ap); - } - - for (int i = 0; i < MAX_CALLBACKS && L.callbacks[i].fn; i++) { - Callback *cb = &L.callbacks[i]; - if (level >= cb->level) { - init_event(&ev, cb->udata); - va_start(ev.ap, fmt); - cb->fn(&ev); - va_end(ev.ap); + if (!L.quiet && level >= L.level) { + init_event(&ev, stderr); + va_start(ev.ap, fmt); + stdout_callback(&ev); + va_end(ev.ap); } - } - unlock(); + for (int i = 0; i < MAX_CALLBACKS && L.callbacks[i].fn; i++) { + Callback *cb = &L.callbacks[i]; + if (level >= cb->level) { + init_event(&ev, cb->udata); + va_start(ev.ap, fmt); + cb->fn(&ev); + va_end(ev.ap); + } + } + + unlock(); } diff --git a/src/log.h b/src/log.h index 262e954..c01f9be 100644 --- a/src/log.h +++ b/src/log.h @@ -39,6 +39,7 @@ typedef struct { const char *fmt; const char *file; struct tm *time; + struct tm time_buf; void *udata; int line; int level; @@ -47,8 +48,6 @@ typedef struct { typedef void (*log_LogFn)(log_Event *ev); typedef void (*log_LockFn)(bool lock, void *udata); - - #define log_debug(...) \ do { \ if (LOG_DEBUG >= RXI_LOGC_DEFAULT_LEVEL) \