diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2018-12-09 00:32:37 -0500 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2018-12-10 22:36:23 -0500 |
commit | dd11144bc81884fa62d90a038ceb5f00c0f88d5e (patch) | |
tree | 2187570131a166061861ccaa2b1400b9760cae7d | |
parent | c2a9692e7849d3a4a7a63ba5a10270eaf67220f6 (diff) | |
download | lighttpd-git-dd11144bc81884fa62d90a038ceb5f00c0f88d5e.tar.gz |
[core] use kill_signal for gw_proc_kill()
After 4 seconds, send kill() every second while waiting for child to exit.
Send host->kill_signal for next 4 seconds, then send SIGTERM (usually same
as host->kill_signal) for following 8 seconds, and finally send SIGKILL
each second after that, until the child process dies.
github: closes #94
-rw-r--r-- | src/gw_backend.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/src/gw_backend.c b/src/gw_backend.c index 0c44ebdd..62183feb 100644 --- a/src/gw_backend.c +++ b/src/gw_backend.c @@ -330,7 +330,8 @@ static void gw_proc_waitpid_log(server *srv, gw_host *host, gw_proc *proc, int s WEXITSTATUS(status), proc->connection_name); } } else if (WIFSIGNALED(status)) { - if (WTERMSIG(status) != SIGTERM && WTERMSIG(status) != SIGINT) { + if (WTERMSIG(status) != SIGTERM && WTERMSIG(status) != SIGINT + && WTERMSIG(status) != host->kill_signal) { log_error_write(srv, __FILE__, __LINE__, "sd", "child signalled:", WTERMSIG(status)); } @@ -701,7 +702,7 @@ static void gw_proc_kill(server *srv, gw_host *host, gw_proc *proc) { host->unused_procs->prev = proc; host->unused_procs = proc; - kill(proc->pid, SIGTERM); + kill(proc->pid, host->kill_signal); gw_proc_set_state(host, proc, PROC_STATE_KILLED); @@ -986,7 +987,7 @@ static int gw_establish_connection(server *srv, gw_host *host, gw_proc *proc, pi return 0; } -static void gw_restart_dead_procs(server *srv, gw_host *host, int debug) { +static void gw_restart_dead_procs(server *srv, gw_host *host, int debug, int trigger) { for (gw_proc *proc = host->first; proc; proc = proc->next) { if (debug > 2) { log_error_write(srv, __FILE__, __LINE__, "sbdddd", @@ -1001,6 +1002,12 @@ static void gw_restart_dead_procs(server *srv, gw_host *host, int debug) { gw_proc_check_enable(srv, host, proc); break; case PROC_STATE_KILLED: + if (trigger && ++proc->disabled_until > 4) { + int sig = (proc->disabled_until <= 8) + ? host->kill_signal + : proc->disabled_until <= 16 ? SIGTERM : SIGKILL; + kill(proc->pid, sig); + } break; case PROC_STATE_DIED_WAIT_FOR_PID: /*(state should not happen in workers if server.max-worker > 0)*/ @@ -1918,7 +1925,7 @@ static handler_t gw_write_error(server *srv, gw_handler_ctx *hctx) { /* (optimization to detect backend process exit while processing a * large number of ready events; (this block could be removed)) */ if (0 == srv->srvconf.max_worker) - gw_restart_dead_procs(srv, hctx->host, hctx->conf.debug); + gw_restart_dead_procs(srv, hctx->host, hctx->conf.debug, 0); /* cleanup this request and let request handler start request again */ if (hctx->reconnects++ < 5) return gw_reconnect(srv, hctx); @@ -2458,7 +2465,7 @@ static void gw_handle_trigger_host(server *srv, gw_host *host, int debug) { gw_proc_waitpid(srv, host, proc); } - gw_restart_dead_procs(srv, host, debug); + gw_restart_dead_procs(srv, host, debug, 1); /* check if adaptive spawning enabled */ if (host->min_procs == host->max_procs) return; |