diff options
-rw-r--r-- | src/nvim/tui/tui.c | 17 | ||||
-rw-r--r-- | src/nvim/ui.c | 6 | ||||
-rw-r--r-- | src/nvim/ui_bridge.c | 4 |
3 files changed, 13 insertions, 14 deletions
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 62bdc61a68..bfebe0442d 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -319,10 +319,16 @@ static void tui_terminal_stop(UI *ui) static void tui_stop(UI *ui) { tui_terminal_stop(ui); - // Flag UI as "stopped". Needed by tui_scheduler (called from main thread). + // Flag UI as "stopped". ui->data = NULL; } +/// Returns true if UI `ui` is stopped. +static bool tui_is_stopped(UI *ui) +{ + return ui->data == NULL; +} + /// Main function of the TUI thread. static void tui_main(UIBridgeData *bridge, UI *ui) { @@ -352,17 +358,17 @@ static void tui_main(UIBridgeData *bridge, UI *ui) event_create(show_termcap_event, 1, data->ut)); // "Active" loop: first ~100 ms of startup. - for (size_t ms = 0; ms < 100 && !ui_is_stopped(ui);) { + for (size_t ms = 0; ms < 100 && !tui_is_stopped(ui);) { ms += (loop_poll_events(&tui_loop, 20) ? 20 : 1); } - if (!ui_is_stopped(ui)) { + if (!tui_is_stopped(ui)) { tui_terminal_after_startup(ui); // Tickle `main_loop` with a dummy event, else the initial "focus-gained" // terminal response may not get processed until user hits a key. loop_schedule_deferred(&main_loop, event_create(tui_dummy_event, 0)); } // "Passive" (I/O-driven) loop: TUI thread "main loop". - while (!ui_is_stopped(ui)) { + while (!tui_is_stopped(ui)) { loop_poll_events(&tui_loop, -1); // tui_loop.events is never processed } @@ -384,9 +390,6 @@ static void tui_dummy_event(void **argv) static void tui_scheduler(Event event, void *d) { UI *ui = d; - if (ui_is_stopped(ui)) { - return; // tui_stop was handled, teardown underway. - } TUIData *data = ui->data; loop_schedule(data->loop, event); // `tui_loop` local to tui_main(). } diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 3f4f17824b..241d70e1b1 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -144,12 +144,6 @@ void ui_builtin_stop(void) UI_CALL(stop); } -/// Returns true if UI `ui` is stopped. -bool ui_is_stopped(UI *ui) -{ - return ui->data == NULL; -} - bool ui_rgb_attached(void) { if (!headless_mode && p_tgc) { diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index c936a17e52..56e0c0c454 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -106,6 +106,9 @@ static void ui_thread_run(void *data) static void ui_bridge_stop(UI *b) { + // Detach brigde first, so that "stop" is the last event the TUI loop + // receives from the main thread. #8041 + ui_detach_impl(b); UIBridgeData *bridge = (UIBridgeData *)b; bool stopped = bridge->stopped = false; UI_BRIDGE_CALL(b, stop, 1, b); @@ -122,7 +125,6 @@ static void ui_bridge_stop(UI *b) uv_mutex_destroy(&bridge->mutex); uv_cond_destroy(&bridge->cond); xfree(bridge->ui); // Threads joined, now safe to free UI container. #7922 - ui_detach_impl(b); xfree(b); } static void ui_bridge_stop_event(void **argv) |