diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2018-04-15 02:03:01 +0200 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2018-04-15 18:23:11 +0200 |
commit | b2c066409d19deb6228b7448e5c0367117031753 (patch) | |
tree | c769aebffd5e246d3faaafdfc1796b8bb3d649b7 /src | |
parent | 142ac021ac88387ef7319dc4eb1f430753480f44 (diff) | |
download | rneovim-b2c066409d19deb6228b7448e5c0367117031753.tar.gz rneovim-b2c066409d19deb6228b7448e5c0367117031753.tar.bz2 rneovim-b2c066409d19deb6228b7448e5c0367117031753.zip |
job-control: children_kill_cb(): do not check elapsed time
1. Don't check elapsed time in children_kill_cb(), it's already implied
by the start-time of the timer itself.
2. Restart timer from children_kill_cb() for PTY jobs, to send SIGKILL
after SIGTERM. There is an edge case where SIGKILL might follow
SIGTERM too quickly, if jobstop() is called near the 2-second timer
window. But this edge case is not worth code complication.
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/event/process.c | 27 | ||||
-rw-r--r-- | src/nvim/event/process.h | 3 |
2 files changed, 15 insertions, 15 deletions
diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index 312da54c76..23433cf495 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -23,7 +23,7 @@ #endif // Time for a process to exit cleanly before we send KILL. -// For pty processes SIGTERM is sent first (in case SIGHUP was not enough). +// For PTY processes SIGTERM is sent first (in case SIGHUP was not enough). #define KILL_TIMEOUT_MS 2000 static bool process_is_tearing_down = false; @@ -209,8 +209,8 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL if (exited || proc->stopped_time) { return; } - proc->stopped_time = os_hrtime(); + switch (proc->type) { case kProcessTypeUv: // Close the process's stdin. If the process doesn't close its own @@ -228,18 +228,16 @@ void process_stop(Process *proc) FUNC_ATTR_NONNULL_ALL abort(); } - // Start a timer to verify that the job process terminated. - ILOG("starting job kill timer"); + // (Re)start timer to verify that stopped process(es) died. uv_timer_start(&proc->loop->children_kill_timer, children_kill_cb, KILL_TIMEOUT_MS, 0); } -/// Sends SIGKILL (or SIGTERM for PTY jobs) to processes that didn't terminate -/// after process_stop() requested them. +/// Sends SIGKILL (or SIGTERM..SIGKILL for PTY jobs) to processes that did +/// not terminate after process_stop(). static void children_kill_cb(uv_timer_t *handle) { Loop *loop = handle->loop->data; - uint64_t now = os_hrtime(); kl_iter(WatcherPtr, loop->children, current) { Process *proc = (*current)->data; @@ -247,12 +245,15 @@ static void children_kill_cb(uv_timer_t *handle) if (exited || !proc->stopped_time) { continue; } - uint64_t elapsed = (now - proc->stopped_time) / 1000000 + 1; - if (elapsed >= KILL_TIMEOUT_MS) { - int sig = proc->type == kProcessTypePty && elapsed < KILL_TIMEOUT_MS * 2 - ? SIGTERM - : SIGKILL; - os_proc_tree_kill(proc->pid, sig); + uint64_t term_sent = UINT64_MAX == proc->stopped_time; + if (kProcessTypePty != proc->type || term_sent) { + os_proc_tree_kill(proc->pid, SIGKILL); + } else { + os_proc_tree_kill(proc->pid, SIGTERM); + proc->stopped_time = UINT64_MAX; // Flag: SIGTERM was sent. + // Restart timer. + uv_timer_start(&proc->loop->children_kill_timer, children_kill_cb, + KILL_TIMEOUT_MS, 0); } } } diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h index 033ce3604b..ba2c2a6a11 100644 --- a/src/nvim/event/process.h +++ b/src/nvim/event/process.h @@ -19,8 +19,7 @@ struct process { Loop *loop; void *data; int pid, status, refcount; - // set to the hrtime of when process_stop was called for the process. - uint64_t stopped_time; + uint64_t stopped_time; // process_stop() timestamp const char *cwd; char **argv; Stream in, out, err; |