]> source.dussan.org Git - rspamd.git/commitdiff
Rework workers signals handlers to be nested if needed.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 8 Oct 2015 15:38:29 +0000 (16:38 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 8 Oct 2015 15:38:29 +0000 (16:38 +0100)
src/fuzzy_storage.c
src/libserver/worker_util.c
src/libserver/worker_util.h
src/rspamd.h

index 7ed5ea6b117bd308fc9078d693aa5f6b4e239b12..873221d8cedd2b1a4bca1708d7130ed588e0f7e1 100644 (file)
@@ -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",
index 71656116a5608304accbdcc6cfcda50728ee3c2c..c9e0521d25dae70b96f08d81dd18ef8fbdb5c3ce 100644 (file)
@@ -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 <google/profiler.h>
 #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);
index 8bc0ceaee914af1637574931c15adfbfa865cf48..f919b0554caeac13a97fca35e6ce38888299d804 100644 (file)
@@ -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
index e085425aa3d2fbd43767d98431b89c3a30980db2..700d0a599cf9191b1963ff9e0e20ee2458cf501d 100644 (file)
@@ -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 {