mirror of
https://github.com/neovim/neovim
synced 2025-07-18 10:11:50 +00:00
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.
This commit is contained in:
@ -16,27 +16,39 @@
|
|||||||
# include "os/pty_proc_win.c.generated.h"
|
# include "os/pty_proc_win.c.generated.h"
|
||||||
#endif
|
#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
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
PtyProc *ptyproc = (PtyProc *)context;
|
PtyProc *ptyproc = (PtyProc *)context;
|
||||||
Proc *proc = (Proc *)ptyproc;
|
Proc *proc = (Proc *)ptyproc;
|
||||||
|
|
||||||
os_conpty_free(ptyproc->conpty);
|
os_conpty_free(ptyproc->conpty);
|
||||||
// NB: pty_proc_finish1() is called on a separate thread,
|
// NB: pty_proc_terminate_cb() is called on a separate thread,
|
||||||
// but the timer only works properly if it's started by the main thread.
|
// but finishing up the process needs to be done on the main thread.
|
||||||
loop_schedule_fast(proc->loop, event_create(start_wait_eof_timer, ptyproc));
|
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
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
PtyProc *ptyproc = (PtyProc *)argv[0];
|
PtyProc *ptyproc = (PtyProc *)argv[0];
|
||||||
|
|
||||||
if (ptyproc->finish_wait != NULL) {
|
if (ptyproc->finish_wait != NULL) {
|
||||||
|
if (pty_proc_can_finish(ptyproc)) {
|
||||||
|
pty_proc_finish(ptyproc);
|
||||||
|
} else {
|
||||||
uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200);
|
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.
|
/// @returns zero on success, or negative error code.
|
||||||
int pty_proc_spawn(PtyProc *ptyproc)
|
int pty_proc_spawn(PtyProc *ptyproc)
|
||||||
@ -120,7 +132,7 @@ int pty_proc_spawn(PtyProc *ptyproc)
|
|||||||
ptyproc->wait_eof_timer.data = (void *)ptyproc;
|
ptyproc->wait_eof_timer.data = (void *)ptyproc;
|
||||||
if (!RegisterWaitForSingleObject(&ptyproc->finish_wait,
|
if (!RegisterWaitForSingleObject(&ptyproc->finish_wait,
|
||||||
proc_handle,
|
proc_handle,
|
||||||
pty_proc_finish1,
|
pty_proc_terminate_cb,
|
||||||
ptyproc,
|
ptyproc,
|
||||||
INFINITE,
|
INFINITE,
|
||||||
WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) {
|
WT_EXECUTEDEFAULT | WT_EXECUTEONLYONCE)) {
|
||||||
@ -213,16 +225,13 @@ static void wait_eof_timer_cb(uv_timer_t *wait_eof_timer)
|
|||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
PtyProc *ptyproc = wait_eof_timer->data;
|
PtyProc *ptyproc = wait_eof_timer->data;
|
||||||
Proc *proc = (Proc *)ptyproc;
|
if (pty_proc_can_finish(ptyproc)) {
|
||||||
|
|
||||||
assert(ptyproc->finish_wait != NULL);
|
|
||||||
if (proc->out.s.closed || proc->out.did_eof || !uv_is_readable(proc->out.s.uvstream)) {
|
|
||||||
uv_timer_stop(&ptyproc->wait_eof_timer);
|
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
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
Proc *proc = (Proc *)ptyproc;
|
Proc *proc = (Proc *)ptyproc;
|
||||||
|
Reference in New Issue
Block a user