diff options
Diffstat (limited to 'src/nvim/os/pty_process_win.c')
-rw-r--r-- | src/nvim/os/pty_process_win.c | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index ca2dce36ea..12831ff05f 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -4,6 +4,8 @@ #include "nvim/ascii_defs.h" #include "nvim/eval/typval.h" +#include "nvim/event/loop.h" +#include "nvim/log.h" #include "nvim/mbyte.h" #include "nvim/memory.h" #include "nvim/os/os.h" @@ -21,9 +23,19 @@ static void CALLBACK pty_process_finish1(void *context, BOOLEAN unused) Process *proc = (Process *)ptyproc; os_conpty_free(ptyproc->conpty); - uv_timer_init(&proc->loop->uv, &ptyproc->wait_eof_timer); - ptyproc->wait_eof_timer.data = (void *)ptyproc; - uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200); + // NB: pty_process_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)); +} + +static void start_wait_eof_timer(void **argv) + FUNC_ATTR_NONNULL_ALL +{ + PtyProcess *ptyproc = (PtyProcess *)argv[0]; + + if (ptyproc->finish_wait != NULL) { + uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200); + } } /// @returns zero on success, or negative error code. @@ -104,6 +116,8 @@ int pty_process_spawn(PtyProcess *ptyproc) } proc->pid = (int)GetProcessId(process_handle); + uv_timer_init(&proc->loop->uv, &ptyproc->wait_eof_timer); + ptyproc->wait_eof_timer.data = (void *)ptyproc; if (!RegisterWaitForSingleObject(&ptyproc->finish_wait, process_handle, pty_process_finish1, @@ -163,6 +177,16 @@ void pty_process_close(PtyProcess *ptyproc) pty_process_close_master(ptyproc); + if (ptyproc->finish_wait != NULL) { + UnregisterWaitEx(ptyproc->finish_wait, NULL); + ptyproc->finish_wait = NULL; + uv_close((uv_handle_t *)&ptyproc->wait_eof_timer, NULL); + } + if (ptyproc->process_handle != NULL) { + CloseHandle(ptyproc->process_handle); + ptyproc->process_handle = NULL; + } + if (proc->internal_close_cb) { proc->internal_close_cb(proc); } @@ -191,6 +215,7 @@ static void wait_eof_timer_cb(uv_timer_t *wait_eof_timer) PtyProcess *ptyproc = wait_eof_timer->data; Process *proc = (Process *)ptyproc; + assert(ptyproc->finish_wait != NULL); if (proc->out.closed || proc->out.did_eof || !uv_is_readable(proc->out.uvstream)) { uv_timer_stop(&ptyproc->wait_eof_timer); pty_process_finish2(ptyproc); @@ -202,16 +227,10 @@ static void pty_process_finish2(PtyProcess *ptyproc) { Process *proc = (Process *)ptyproc; - UnregisterWaitEx(ptyproc->finish_wait, NULL); - uv_close((uv_handle_t *)&ptyproc->wait_eof_timer, NULL); - DWORD exit_code = 0; GetExitCodeProcess(ptyproc->process_handle, &exit_code); proc->status = proc->exit_signal ? 128 + proc->exit_signal : (int)exit_code; - CloseHandle(ptyproc->process_handle); - ptyproc->process_handle = NULL; - proc->internal_exit_cb(proc); } @@ -407,3 +426,15 @@ cleanup: return rc; } + +PtyProcess pty_process_init(Loop *loop, void *data) +{ + PtyProcess rv; + rv.process = process_init(loop, kProcessTypePty, data); + rv.width = 80; + rv.height = 24; + rv.conpty = NULL; + rv.finish_wait = NULL; + rv.process_handle = NULL; + return rv; +} |