From: Vsevolod Stakhov Date: Sun, 17 Sep 2017 09:36:07 +0000 (+0100) Subject: [Feature] Improve subprocesses termination handle X-Git-Tag: 1.7.0~628 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3e23c6b1128023a94a440b118eabf8df5b33090f;p=thirdparty%2Frspamd.git [Feature] Improve subprocesses termination handle --- diff --git a/src/libserver/worker_util.c b/src/libserver/worker_util.c index 2edaa2612b..38e58aa838 100644 --- a/src/libserver/worker_util.c +++ b/src/libserver/worker_util.c @@ -186,6 +186,34 @@ rspamd_worker_ignore_signal (int signo) sigaction (signo, &sig, NULL); } +static void +rspamd_worker_default_signal (int signo) +{ + struct sigaction sig; + + sigemptyset (&sig.sa_mask); + sigaddset (&sig.sa_mask, signo); + sig.sa_handler = SIG_DFL; + sig.sa_flags = 0; + sigaction (signo, &sig, NULL); +} + +static void +rspamd_sigh_free (void *p) +{ + struct rspamd_worker_signal_handler *sigh = p; + struct rspamd_worker_signal_cb *cb, *tmp; + + DL_FOREACH_SAFE (sigh->cb, cb, tmp) { + DL_DELETE (sigh->cb, cb); + g_free (cb); + } + + event_del (&sigh->ev); + rspamd_worker_default_signal (sigh->signo); + g_free (sigh); +} + void rspamd_worker_set_signal_handler (int signo, struct rspamd_worker *worker, struct event_base *base, @@ -219,7 +247,7 @@ rspamd_worker_set_signal_handler (int signo, struct rspamd_worker *worker, DL_APPEND (sigh->cb, cb); } -static void +void rspamd_worker_init_signals (struct rspamd_worker *worker, struct event_base *base) { struct sigaction signals; @@ -274,7 +302,7 @@ rspamd_prepare_worker (struct rspamd_worker *worker, const char *name, worker->srv->pid = getpid (); worker->signal_events = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, g_free); + NULL, rspamd_sigh_free); ev_base = event_init (); @@ -662,6 +690,20 @@ rspamd_worker_block_signals (void) sigprocmask (SIG_BLOCK, &set, NULL); } +void +rspamd_worker_unblock_signals (void) +{ + sigset_t set; + + sigemptyset (&set); + sigaddset (&set, SIGTERM); + sigaddset (&set, SIGINT); + sigaddset (&set, SIGHUP); + sigaddset (&set, SIGUSR1); + sigaddset (&set, SIGUSR2); + sigprocmask (SIG_UNBLOCK, &set, NULL); +} + void rspamd_hard_terminate (struct rspamd_main *rspamd_main) { diff --git a/src/libserver/worker_util.h b/src/libserver/worker_util.h index d8decbac83..3af9c961dc 100644 --- a/src/libserver/worker_util.h +++ b/src/libserver/worker_util.h @@ -30,6 +30,12 @@ typedef void (*rspamd_sig_handler_t) (gint, siginfo_t *, void *); struct rspamd_worker; struct rspamd_worker_signal_handler; +/** + * Init basic signals for a worker + * @param worker + * @param base + */ +void rspamd_worker_init_signals (struct rspamd_worker *worker, struct event_base *base); /** * Prepare worker's startup * @param worker worker structure @@ -123,6 +129,11 @@ void rspamd_worker_stop_accept (struct rspamd_worker *worker); */ void rspamd_worker_block_signals (void); +/** + * Unblock signals + */ +void rspamd_worker_unblock_signals (void); + /** * Kill rspamd main and all workers * @param rspamd_main diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c index 2aed2f7a9b..b72c80a15e 100644 --- a/src/lua/lua_common.c +++ b/src/lua/lua_common.c @@ -1695,6 +1695,8 @@ lua_worker_spawn_process (lua_State *L) /* Here we assume that we can block on writing results */ rspamd_socket_blocking (cbdata->sp[1]); event_reinit (cbdata->ev_base); + g_hash_table_remove_all (w->signal_events); + rspamd_worker_unblock_signals (); rspamd_lua_execute_lua_subprocess (L, cbdata); /* Wait for parent to reply and exit */ diff --git a/src/rspamd.c b/src/rspamd.c index 01377e7cf4..1b24fd67aa 100644 --- a/src/rspamd.c +++ b/src/rspamd.c @@ -730,10 +730,22 @@ wait_for_workers (gpointer key, gpointer value, gpointer unused) } } } + else if (nowait) { + kill (w->pid, 0); + + if (errno != ESRCH) { + return FALSE; + } + else { + goto finished; + } + } return FALSE; } + + finished: msg_info_main ("%s process %P terminated %s", g_quark_to_string (w->type), w->pid,