aboutsummaryrefslogtreecommitdiffstats
path: root/src/libserver/worker_util.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-10-08 16:38:29 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-10-08 16:38:29 +0100
commitdb7dba5ba7daec61ca505e0299bfbf46d7f22167 (patch)
tree7e7fe14a2f46d7e631c8677598d71b5f8df0d6ec /src/libserver/worker_util.c
parent0f74ebee2bcb2714390bdc861bbec2017093289c (diff)
downloadrspamd-db7dba5ba7daec61ca505e0299bfbf46d7f22167.tar.gz
rspamd-db7dba5ba7daec61ca505e0299bfbf46d7f22167.zip
Rework workers signals handlers to be nested if needed.
Diffstat (limited to 'src/libserver/worker_util.c')
-rw-r--r--src/libserver/worker_util.c88
1 files changed, 52 insertions, 36 deletions
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 <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 ();
@@ -128,6 +114,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)
{
struct sigaction sig;
@@ -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);