aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/event
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2022-05-02 21:10:01 +0200
committerbfredl <bjorn.linse@gmail.com>2022-12-31 13:25:26 +0100
commit43e8ec92de9e0850e7d202cb7ff9051bc408447e (patch)
treefcaef65604e05fb9cc34cf7543c7d92af9c38dcf /src/nvim/event
parent24488169564c39a506c235bf6a33b8e23a8cb528 (diff)
downloadrneovim-43e8ec92de9e0850e7d202cb7ff9051bc408447e.tar.gz
rneovim-43e8ec92de9e0850e7d202cb7ff9051bc408447e.tar.bz2
rneovim-43e8ec92de9e0850e7d202cb7ff9051bc408447e.zip
fix(tui): more work in the TUI
Diffstat (limited to 'src/nvim/event')
-rw-r--r--src/nvim/event/libuv_process.c4
-rw-r--r--src/nvim/event/process.c35
2 files changed, 34 insertions, 5 deletions
diff --git a/src/nvim/event/libuv_process.c b/src/nvim/event/libuv_process.c
index cf4ff16c4d..811d96ff93 100644
--- a/src/nvim/event/libuv_process.c
+++ b/src/nvim/event/libuv_process.c
@@ -47,8 +47,8 @@ int libuv_process_spawn(LibuvProcess *uvproc)
uvproc->uvstdio[1].flags = UV_IGNORE;
uvproc->uvstdio[2].flags = UV_IGNORE;
- // TODO: this should just be single flag!
- if (TUI_process && !is_remote_client && !stdin_isatty) {
+ if (ui_client_forward_stdin) {
+ assert(UI_CLIENT_STDIN_FD == 3);
uvproc->uvopts.stdio_count = 4;
uvproc->uvstdio[3].data.fd = 0;
uvproc->uvstdio[3].flags = UV_INHERIT_FD;
diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c
index 52a9394e88..2fa789ac9a 100644
--- a/src/nvim/event/process.c
+++ b/src/nvim/event/process.c
@@ -14,6 +14,7 @@
#include "nvim/globals.h"
#include "nvim/log.h"
#include "nvim/macros.h"
+#include "nvim/main.h"
#include "nvim/os/process.h"
#include "nvim/os/pty_process.h"
#include "nvim/os/shell.h"
@@ -35,6 +36,9 @@ void __gcov_flush(void);
static bool process_is_tearing_down = false;
+// Delay exit until handles are closed, to avoid deadlocks
+static int exit_need_delay = 0;
+
/// @returns zero on success, or negative error code
int process_spawn(Process *proc, bool in, bool out, bool err)
FUNC_ATTR_NONNULL_ALL
@@ -398,16 +402,41 @@ static void process_close_handles(void **argv)
exit_need_delay--;
}
+static void exit_delay_cb(uv_timer_t *handle)
+{
+ uv_timer_stop(&main_loop.exit_delay_timer);
+ multiqueue_put(main_loop.fast_events, exit_event, 1, main_loop.exit_delay_timer.data);
+}
+
+static void exit_event(void **argv)
+{
+ int status = (int)(intptr_t)argv[0];
+ if (exit_need_delay) {
+ main_loop.exit_delay_timer.data = argv[0];
+ uv_timer_start(&main_loop.exit_delay_timer, exit_delay_cb, 0, 0);
+ return;
+ }
+
+ if (!exiting) {
+ os_exit(status);
+ }
+}
+
+void exit_from_channel(int status)
+{
+ multiqueue_put(main_loop.fast_events, exit_event, 1, status);
+}
+
static void on_process_exit(Process *proc)
{
Loop *loop = proc->loop;
ILOG("exited: pid=%d status=%d stoptime=%" PRIu64, proc->pid, proc->status,
proc->stopped_time);
- if (TUI_process && !is_remote_client) {
- // Set only in "builtin" TUI
- server_process_exit_status = proc->status;
+ if (ui_client_channel_id) {
+ exit_from_channel(proc->status);
}
+
// Process has terminated, but there could still be data to be read from the
// OS. We are still in the libuv loop, so we cannot call code that polls for
// more data directly. Instead delay the reading after the libuv loop by