aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarkstegeman <markstegeman@users.noreply.github.com>2025-03-12 13:35:14 +0100
committerGitHub <noreply@github.com>2025-03-12 05:35:14 -0700
commit69a19295f8fe90356011eff2b7fa67b0593fffcc (patch)
treec802618f40c880160b7f3602f802b09f0c60b244
parent3bc72a4980ab2ffe0c3c5300b79b93905b0237e3 (diff)
downloadrneovim-69a19295f8fe90356011eff2b7fa67b0593fffcc.tar.gz
rneovim-69a19295f8fe90356011eff2b7fa67b0593fffcc.tar.bz2
rneovim-69a19295f8fe90356011eff2b7fa67b0593fffcc.zip
fix(terminal): delay when finishing terminal process #32846
Problem: On Windows, the first attempt at finishing up after a terminal process terminates is delayed by 200ms, even if it would be possible to finish up immediately. Solution: Make the first attempt at finishing up immediately after the process terminates.
-rw-r--r--src/nvim/os/pty_proc_win.c35
1 files changed, 22 insertions, 13 deletions
diff --git a/src/nvim/os/pty_proc_win.c b/src/nvim/os/pty_proc_win.c
index 5bd6eead51..5a45f09b3a 100644
--- a/src/nvim/os/pty_proc_win.c
+++ b/src/nvim/os/pty_proc_win.c
@@ -16,28 +16,40 @@
# include "os/pty_proc_win.c.generated.h"
#endif
-static void CALLBACK pty_proc_finish1(void *context, BOOLEAN unused)
+static void CALLBACK pty_proc_terminate_cb(void *context, BOOLEAN unused)
FUNC_ATTR_NONNULL_ALL
{
PtyProc *ptyproc = (PtyProc *)context;
Proc *proc = (Proc *)ptyproc;
os_conpty_free(ptyproc->conpty);
- // NB: pty_proc_finish1() is called on a separate thread,
- // but the timer only works properly if it's started by the main thread.
- loop_schedule_fast(proc->loop, event_create(start_wait_eof_timer, ptyproc));
+ // NB: pty_proc_terminate_cb() is called on a separate thread,
+ // but finishing up the process needs to be done on the main thread.
+ loop_schedule_fast(proc->loop, event_create(pty_proc_finish_when_eof, ptyproc));
}
-static void start_wait_eof_timer(void **argv)
+static void pty_proc_finish_when_eof(void **argv)
FUNC_ATTR_NONNULL_ALL
{
PtyProc *ptyproc = (PtyProc *)argv[0];
if (ptyproc->finish_wait != NULL) {
- uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200);
+ if (pty_proc_can_finish(ptyproc)) {
+ pty_proc_finish(ptyproc);
+ } else {
+ uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200);
+ }
}
}
+static bool pty_proc_can_finish(PtyProc *ptyproc)
+{
+ Proc *proc = (Proc *)ptyproc;
+
+ assert(ptyproc->finish_wait != NULL);
+ return proc->out.s.closed || proc->out.did_eof || !uv_is_readable(proc->out.s.uvstream);
+}
+
/// @returns zero on success, or negative error code.
int pty_proc_spawn(PtyProc *ptyproc)
FUNC_ATTR_NONNULL_ALL
@@ -120,7 +132,7 @@ int pty_proc_spawn(PtyProc *ptyproc)
ptyproc->wait_eof_timer.data = (void *)ptyproc;
if (!RegisterWaitForSingleObject(&ptyproc->finish_wait,
proc_handle,
- pty_proc_finish1,
+ pty_proc_terminate_cb,
ptyproc,
INFINITE,
WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) {
@@ -213,16 +225,13 @@ static void wait_eof_timer_cb(uv_timer_t *wait_eof_timer)
FUNC_ATTR_NONNULL_ALL
{
PtyProc *ptyproc = wait_eof_timer->data;
- Proc *proc = (Proc *)ptyproc;
-
- assert(ptyproc->finish_wait != NULL);
- if (proc->out.s.closed || proc->out.did_eof || !uv_is_readable(proc->out.s.uvstream)) {
+ if (pty_proc_can_finish(ptyproc)) {
uv_timer_stop(&ptyproc->wait_eof_timer);
- pty_proc_finish2(ptyproc);
+ pty_proc_finish(ptyproc);
}
}
-static void pty_proc_finish2(PtyProc *ptyproc)
+static void pty_proc_finish(PtyProc *ptyproc)
FUNC_ATTR_NONNULL_ALL
{
Proc *proc = (Proc *)ptyproc;