diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-02-29 15:18:39 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-02-29 15:18:39 +0000 |
commit | 2cbece2248e8a90b7a71319ae59b638b36ced6df (patch) | |
tree | 476da92d29a0bd275628dc02ee3e50e79710c3d7 | |
parent | 40c93053ef5687ad722203c05ab7017711e482a1 (diff) | |
download | rspamd-2cbece2248e8a90b7a71319ae59b638b36ced6df.tar.gz rspamd-2cbece2248e8a90b7a71319ae59b638b36ced6df.zip |
[Feature] Add lockless logging
Sometimes, it is needed to turn off logging mutex to avoid recursive
mutex obtaining. It is especially useful to do it within children wait
code in the main processes dispatcher.
-rw-r--r-- | src/libutil/logger.c | 42 | ||||
-rw-r--r-- | src/libutil/logger.h | 10 | ||||
-rw-r--r-- | src/rspamd.c | 5 |
3 files changed, 51 insertions, 6 deletions
diff --git a/src/libutil/logger.c b/src/libutil/logger.c index 56f7822a5..e6c188113 100644 --- a/src/libutil/logger.c +++ b/src/libutil/logger.c @@ -48,6 +48,7 @@ struct rspamd_logger_s { gboolean enabled; gboolean is_debug; gboolean throttling; + gboolean no_lock; time_t throttling_time; sig_atomic_t do_reopen_log; enum rspamd_log_type type; @@ -69,6 +70,18 @@ static const gchar lf_chr = '\n'; static rspamd_logger_t *default_logger = NULL; +#define RSPAMD_LOGGER_LOCK(l) do { \ + if ((l) != NULL && !(l)->no_lock) { \ + rspamd_mempool_lock_mutex ((l)->mtx); \ + } \ +} while (0) + +#define RSPAMD_LOGGER_UNLOCK(l) do { \ + if ((l) != NULL && !(l)->no_lock) { \ + rspamd_mempool_unlock_mutex ((l)->mtx); \ + } \ +} while (0) + static void syslog_log_function (const gchar *log_domain, const gchar *module, @@ -456,14 +469,14 @@ rspamd_common_logv (rspamd_logger_t *rspamd_log, GLogLevelFlags log_level, else { if (rspamd_logger_need_log (rspamd_log, log_level, module)) { rspamd_vsnprintf (logbuf, sizeof (logbuf), fmt, args); - rspamd_mempool_lock_mutex (rspamd_log->mtx); + RSPAMD_LOGGER_LOCK (rspamd_log); rspamd_log->log_func (NULL, module, id, function, log_level, logbuf, FALSE, rspamd_log); - rspamd_mempool_unlock_mutex (rspamd_log->mtx); + RSPAMD_LOGGER_UNLOCK (rspamd_log); } switch (log_level) { @@ -918,7 +931,8 @@ rspamd_conditional_debug (rspamd_logger_t *rspamd_log, return; } } - rspamd_mempool_lock_mutex (rspamd_log->mtx); + + RSPAMD_LOGGER_LOCK (rspamd_log); va_start (vp, fmt); end = rspamd_vsnprintf (logbuf, sizeof (logbuf), fmt, vp); *end = '\0'; @@ -929,7 +943,7 @@ rspamd_conditional_debug (rspamd_logger_t *rspamd_log, logbuf, TRUE, rspamd_log); - rspamd_mempool_unlock_mutex (rspamd_log->mtx); + RSPAMD_LOGGER_UNLOCK (rspamd_log); } } @@ -946,14 +960,14 @@ rspamd_glib_log_function (const gchar *log_domain, if (rspamd_log->enabled && rspamd_logger_need_log (rspamd_log, log_level, NULL)) { - rspamd_mempool_lock_mutex (rspamd_log->mtx); + RSPAMD_LOGGER_LOCK (rspamd_log); rspamd_log->log_func (log_domain, "glib", NULL, NULL, log_level, message, FALSE, rspamd_log); - rspamd_mempool_unlock_mutex (rspamd_log->mtx); + RSPAMD_LOGGER_UNLOCK (rspamd_log); } } @@ -992,3 +1006,19 @@ rspamd_log_counters (rspamd_logger_t *logger) return NULL; } + +void +rspamd_log_nolock (rspamd_logger_t *logger) +{ + if (logger) { + logger->no_lock = TRUE; + } +} + +void +rspamd_log_lock (rspamd_logger_t *logger) +{ + if (logger) { + logger->no_lock = FALSE; + } +} diff --git a/src/libutil/logger.h b/src/libutil/logger.h index 7bf8307c8..2523efad3 100644 --- a/src/libutil/logger.h +++ b/src/libutil/logger.h @@ -124,6 +124,16 @@ void rspamd_log_debug (rspamd_logger_t *logger); void rspamd_log_nodebug (rspamd_logger_t *logger); /** + * Turn off locking on logger (useful to avoid races) + */ +void rspamd_log_nolock (rspamd_logger_t *logger); + +/** + * Turn on locking to avoid log output mix + */ +void rspamd_log_lock (rspamd_logger_t *logger); + +/** * Return array of counters (4 numbers): * 0 - errors * 1 - warnings diff --git a/src/rspamd.c b/src/rspamd.c index 8ff95cd7a..cada080b9 100644 --- a/src/rspamd.c +++ b/src/rspamd.c @@ -821,6 +821,9 @@ rspamd_cld_handler (gint signo, short what, gpointer arg) struct rspamd_worker *cur; pid_t wrk; + /* Turn off locking for logger */ + rspamd_log_nolock (rspamd_main->logger); + msg_debug_main ("catch SIGCHLD signal, finding terminated worker"); /* Remove dead child form children list */ wrk = waitpid (0, &res, 0); @@ -891,6 +894,8 @@ rspamd_cld_handler (gint signo, short what, gpointer arg) } } } + + rspamd_log_lock (rspamd_main->logger); } static void |