From: Vsevolod Stakhov Date: Thu, 8 Oct 2015 15:38:29 +0000 (+0100) Subject: Rework workers signals handlers to be nested if needed. X-Git-Tag: 1.0.5~54 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=db7dba5ba7daec61ca505e0299bfbf46d7f22167;p=rspamd.git Rework workers signals handlers to be nested if needed. --- diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c index 7ed5ea6b1..873221d8c 100644 --- a/src/fuzzy_storage.c +++ b/src/fuzzy_storage.c @@ -507,7 +507,6 @@ start_fuzzy (struct rspamd_worker *worker) struct rspamd_fuzzy_storage_ctx *ctx = worker->ctx; GError *err = NULL; gdouble next_check; - struct event usr2_ ctx->ev_base = rspamd_prepare_worker (worker, "fuzzy", diff --git a/src/libserver/worker_util.c b/src/libserver/worker_util.c index 71656116a..c9e0521d2 100644 --- a/src/libserver/worker_util.c +++ b/src/libserver/worker_util.c @@ -27,6 +27,8 @@ #include "lua/lua_common.h" #include "worker_util.h" #include "unix-std.h" +#include "utlist.h" + #ifdef WITH_GPERF_TOOLS #include #endif @@ -58,10 +60,8 @@ sig_atomic_t wanna_die = 0; * Config reload is designed by sending sigusr2 to active workers and pending shutdown of them */ static void -rspamd_worker_usr2_handler (gint fd, short what, void *arg) +rspamd_worker_usr2_handler (struct rspamd_worker_signal_handler *sigh, void *arg) { - struct rspamd_worker_signal_handler *sigh = - (struct rspamd_worker_signal_handler *)arg; /* Do not accept new connections, preparing to end worker's process */ struct timeval tv; @@ -76,9 +76,6 @@ rspamd_worker_usr2_handler (gint fd, short what, void *arg) "worker's shutdown is pending in %d sec", SOFT_SHUTDOWN_TIME); event_base_loopexit (sigh->base, &tv); - if (sigh->post_handler) { - sigh->post_handler (sigh->handler_data); - } rspamd_worker_stop_accept (sigh->worker); } } @@ -87,23 +84,14 @@ rspamd_worker_usr2_handler (gint fd, short what, void *arg) * Reopen log is designed by sending sigusr1 to active workers and pending shutdown of them */ static void -rspamd_worker_usr1_handler (gint fd, short what, void *arg) +rspamd_worker_usr1_handler (struct rspamd_worker_signal_handler *sigh, void *arg) { - struct rspamd_worker_signal_handler *sigh = - (struct rspamd_worker_signal_handler *)arg; - rspamd_log_reopen (sigh->worker->srv->logger); - - if (sigh->post_handler) { - sigh->post_handler (sigh->handler_data); - } } static void -rspamd_worker_term_handler (gint fd, short what, void *arg) +rspamd_worker_term_handler (struct rspamd_worker_signal_handler *sigh, void *arg) { - struct rspamd_worker_signal_handler *sigh = - (struct rspamd_worker_signal_handler *)arg; struct timeval tv; if (!wanna_die) { @@ -116,9 +104,7 @@ rspamd_worker_term_handler (gint fd, short what, void *arg) wanna_die = 1; tv.tv_sec = 0; tv.tv_usec = 0; - if (sigh->post_handler) { - sigh->post_handler (sigh->handler_data); - } + event_base_loopexit (sigh->base, &tv); #ifdef WITH_GPERF_TOOLS ProfilerStop (); @@ -127,6 +113,22 @@ rspamd_worker_term_handler (gint fd, short what, void *arg) } } +static void +rspamd_worker_signal_handler (int fd, short what, void *arg) +{ + struct rspamd_worker_signal_handler *sigh = + (struct rspamd_worker_signal_handler *) arg; + struct rspamd_worker_signal_cb *cb; + + cb = sigh->cb; + + /* Call all signal handlers registered */ + while (cb) { + cb->handler (sigh, cb->handler_data); + cb = cb->next; + } +} + static void rspamd_worker_ignore_signal (int signo) { @@ -139,23 +141,37 @@ rspamd_worker_ignore_signal (int signo) sigaction (signo, &sig, NULL); } -static void +void rspamd_worker_set_signal_handler (int signo, struct rspamd_worker *worker, - struct event_base *base, void (*handler)(int, short, void *)) + struct event_base *base, + void (*handler)(struct rspamd_worker_signal_handler *sigh, void *), + void *handler_data) { struct rspamd_worker_signal_handler *sigh; + struct rspamd_worker_signal_cb *cb; + + sigh = g_hash_table_lookup (worker->signal_events, GINT_TO_POINTER (signo)); - sigh = g_malloc0 (sizeof (*sigh)); - sigh->signo = signo; - sigh->worker = worker; - sigh->base = base; - sigh->enabled = TRUE; + if (sigh == NULL) { + sigh = g_malloc0 (sizeof (*sigh)); + sigh->signo = signo; + sigh->worker = worker; + sigh->base = base; + sigh->enabled = TRUE; - signal_set (&sigh->ev, signo, handler, sigh); - event_base_set (base, &sigh->ev); - signal_add (&sigh->ev, NULL); + signal_set (&sigh->ev, signo, rspamd_worker_signal_handler, sigh); + event_base_set (base, &sigh->ev); + signal_add (&sigh->ev, NULL); + + g_hash_table_insert (worker->signal_events, + GINT_TO_POINTER (signo), + sigh); + } - g_hash_table_insert (worker->signal_events, GINT_TO_POINTER (signo), sigh); + cb = g_malloc0 (sizeof (*cb)); + cb->handler = handler; + cb->handler_data = handler_data; + DL_APPEND (sigh->cb, cb); } static void @@ -169,17 +185,17 @@ rspamd_worker_init_signals (struct rspamd_worker *worker, struct event_base *bas /* A set of terminating signals */ rspamd_worker_set_signal_handler (SIGTERM, worker, base, - rspamd_worker_term_handler); + rspamd_worker_term_handler, NULL); rspamd_worker_set_signal_handler (SIGINT, worker, base, - rspamd_worker_term_handler); + rspamd_worker_term_handler, NULL); rspamd_worker_set_signal_handler (SIGHUP, worker, base, - rspamd_worker_term_handler); + rspamd_worker_term_handler, NULL); /* Special purpose signals */ rspamd_worker_set_signal_handler (SIGUSR1, worker, base, - rspamd_worker_usr1_handler); + rspamd_worker_usr1_handler, NULL); rspamd_worker_set_signal_handler (SIGUSR2, worker, base, - rspamd_worker_usr2_handler); + rspamd_worker_usr2_handler, NULL); /* Unblock all signals processed */ sigemptyset (&signals.sa_mask); diff --git a/src/libserver/worker_util.h b/src/libserver/worker_util.h index 8bc0ceaee..f919b0554 100644 --- a/src/libserver/worker_util.h +++ b/src/libserver/worker_util.h @@ -35,6 +35,7 @@ typedef void (*rspamd_sig_handler_t) (gint, siginfo_t *, void *); #endif struct rspamd_worker; +struct rspamd_worker_signal_handler; /** * Prepare worker's startup @@ -48,6 +49,15 @@ struct event_base * rspamd_prepare_worker (struct rspamd_worker *worker, const char *name, void (*accept_handler)(int, short, void *)); +/** + * Set special signal handler for a worker + */ +void rspamd_worker_set_signal_handler (int signo, + struct rspamd_worker *worker, + struct event_base *base, + void (*handler) (struct rspamd_worker_signal_handler *, void *), + void *handler_data); + /** * Stop accepting new connections for a worker * @param worker diff --git a/src/rspamd.h b/src/rspamd.h index e085425aa..700d0a599 100644 --- a/src/rspamd.h +++ b/src/rspamd.h @@ -53,14 +53,21 @@ struct rspamd_worker { gpointer ctx; /**< worker's specific data */ }; +struct rspamd_worker_signal_handler; + +struct rspamd_worker_signal_cb { + void (*handler) (struct rspamd_worker_signal_handler *, void *ud); + void *handler_data; + struct rspamd_worker_signal_cb *next, *prev; +}; + struct rspamd_worker_signal_handler { gint signo; gboolean enabled; struct event ev; struct event_base *base; struct rspamd_worker *worker; - void (*post_handler)(void *ud); - void *handler_data; + struct rspamd_worker_signal_cb *cb; }; struct rspamd_controller_pbkdf {