From 8533adb4844b771b84dac2141fa2fa60e0487b47 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 21 Dec 2023 16:50:05 +0800 Subject: refactor(IWYU): move decor provider types to decoration_defs.h (#26692) --- src/nvim/os/pty_process_win.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/os/pty_process_win.c') diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index ca2dce36ea..563a79358c 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -4,6 +4,7 @@ #include "nvim/ascii_defs.h" #include "nvim/eval/typval.h" +#include "nvim/log.h" #include "nvim/mbyte.h" #include "nvim/memory.h" #include "nvim/os/os.h" -- cgit From af93a74a0f4afa9a3a4f55ffdf28141eaf776d22 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 18 Dec 2023 10:55:23 +0100 Subject: refactor: run IWYU on entire repo Reference: https://github.com/neovim/neovim/issues/6371. --- src/nvim/os/pty_process_win.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/os/pty_process_win.c') diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index 563a79358c..e898879729 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -4,6 +4,7 @@ #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" -- cgit From 1813661a6197c76ea6621284570aca1d56597099 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 4 Jan 2024 15:38:16 +0100 Subject: refactor(IWYU): fix headers Remove `export` pramgas from defs headers as it causes IWYU to believe that the definitions from the defs headers comes from main header, which is not what we really want. --- src/nvim/os/pty_process_win.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/nvim/os/pty_process_win.c') diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index e898879729..06ffb5694c 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -409,3 +409,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; +} -- cgit From 268066e01400f55b0c38716f0d6ee3dece10c43e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 26 Feb 2024 09:47:49 +0800 Subject: fix(process): start pty process eof timer on main thread (#27625) --- src/nvim/os/pty_process_win.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/nvim/os/pty_process_win.c') diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index 06ffb5694c..fdc06f9804 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -23,6 +23,17 @@ static void CALLBACK pty_process_finish1(void *context, BOOLEAN unused) Process *proc = (Process *)ptyproc; os_conpty_free(ptyproc->conpty); + // 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]; + Process *proc = (Process *)ptyproc; + 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); -- cgit From 3e569d440b8e5a2b190a7013081d29cb7e04af01 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 7 Mar 2024 18:05:55 +0800 Subject: fix(process): close handles and timer in pty_process_close() (#27760) This should prevent use-after-free on exit on Windows. --- src/nvim/os/pty_process_win.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src/nvim/os/pty_process_win.c') diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index fdc06f9804..cce27c31b4 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -34,8 +34,6 @@ static void start_wait_eof_timer(void **argv) PtyProcess *ptyproc = (PtyProcess *)argv[0]; Process *proc = (Process *)ptyproc; - 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); } @@ -117,6 +115,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, @@ -176,6 +176,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); } @@ -215,16 +225,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); } -- cgit From d0b3c872192152d5b09a92e53e3986b9fe64a3d9 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 8 Mar 2024 09:18:03 +0800 Subject: fix(process): avoid potential data race on exit (#27769) On exit, pty_process_close() may be called after pty_process_finish1() but before start_wait_eof_timer(), in which case the timer shouldn't be started because pty_process_close() has already closed it. --- src/nvim/os/pty_process_win.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/nvim/os/pty_process_win.c') diff --git a/src/nvim/os/pty_process_win.c b/src/nvim/os/pty_process_win.c index cce27c31b4..12831ff05f 100644 --- a/src/nvim/os/pty_process_win.c +++ b/src/nvim/os/pty_process_win.c @@ -32,9 +32,10 @@ static void start_wait_eof_timer(void **argv) FUNC_ATTR_NONNULL_ALL { PtyProcess *ptyproc = (PtyProcess *)argv[0]; - Process *proc = (Process *)ptyproc; - uv_timer_start(&ptyproc->wait_eof_timer, wait_eof_timer_cb, 200, 200); + 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. @@ -214,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); -- cgit