summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2018-12-09 00:32:37 -0500
committerGlenn Strauss <gstrauss@gluelogic.com>2018-12-10 22:36:23 -0500
commitdd11144bc81884fa62d90a038ceb5f00c0f88d5e (patch)
tree2187570131a166061861ccaa2b1400b9760cae7d
parentc2a9692e7849d3a4a7a63ba5a10270eaf67220f6 (diff)
downloadlighttpd-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.c17
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;