Browse Source

[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.
pull/543/head
Vsevolod Stakhov 10 years ago
parent
commit
2cbece2248
  1. 42
      src/libutil/logger.c
  2. 10
      src/libutil/logger.h
  3. 5
      src/rspamd.c

42
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;
}
}

10
src/libutil/logger.h

@ -123,6 +123,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

5
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

Loading…
Cancel
Save