aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/event/process.c27
-rw-r--r--src/nvim/event/process.h3
-rw-r--r--test/functional/autocmd/termclose_spec.lua6
3 files changed, 18 insertions, 18 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;
diff --git a/test/functional/autocmd/termclose_spec.lua b/test/functional/autocmd/termclose_spec.lua
index 0804579a4f..db4e5379d0 100644
--- a/test/functional/autocmd/termclose_spec.lua
+++ b/test/functional/autocmd/termclose_spec.lua
@@ -32,7 +32,7 @@ describe('TermClose event', function()
end)
it('kills job trapping SIGTERM', function()
- if helpers.pending_win32(pending) then return end
+ if iswin() then return end
nvim('set_option', 'shell', 'sh')
nvim('set_option', 'shellcmdflag', '-c')
command([[ let g:test_job = jobstart('trap "" TERM && echo 1 && sleep 60', { ]]
@@ -51,8 +51,8 @@ describe('TermClose event', function()
ok(duration <= 4000) -- Epsilon for slow CI
end)
- it('kills pty job trapping SIGHUP and SIGTERM', function()
- if helpers.pending_win32(pending) then return end
+ it('kills PTY job trapping SIGHUP and SIGTERM', function()
+ if iswin() then return end
nvim('set_option', 'shell', 'sh')
nvim('set_option', 'shellcmdflag', '-c')
command([[ let g:test_job = jobstart('trap "" HUP TERM && echo 1 && sleep 60', { ]]