aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-02-29 15:18:39 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-02-29 15:18:39 +0000
commit2cbece2248e8a90b7a71319ae59b638b36ced6df (patch)
tree476da92d29a0bd275628dc02ee3e50e79710c3d7
parent40c93053ef5687ad722203c05ab7017711e482a1 (diff)
downloadrspamd-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.c42
-rw-r--r--src/libutil/logger.h10
-rw-r--r--src/rspamd.c5
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