aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Anders <greg@gpanders.com>2025-03-11 15:35:12 -0500
committerGitHub <noreply@github.com>2025-03-11 15:35:12 -0500
commit6b8c56c7f6dae922d874b34ca95d0e7ff2496944 (patch)
treec321a25a4629d29178213d2ec1e3c017aceeb4b1
parentdc1888fcfbba1f969ddc01100c466057dccbb58f (diff)
downloadrneovim-6b8c56c7f6dae922d874b34ca95d0e7ff2496944.tar.gz
rneovim-6b8c56c7f6dae922d874b34ca95d0e7ff2496944.tar.bz2
rneovim-6b8c56c7f6dae922d874b34ca95d0e7ff2496944.zip
fix(ui): schedule UI detach (#32827)
When a UI detaches it will execute any UILeave events. Autocommands cannot run in a libuv handler because they will in turn poll the event loop, which results in recursive loop execution. So we schedule the callback to detach the UI on the main event queue. We also have to schedule the exit when the RPC channel is closed to ensure it does not run until after `remote_ui_disconnect` has run, otherwise it will hang.
-rw-r--r--src/nvim/msgpack_rpc/channel.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/nvim/msgpack_rpc/channel.c b/src/nvim/msgpack_rpc/channel.c
index 1d24198455..edc4442785 100644
--- a/src/nvim/msgpack_rpc/channel.c
+++ b/src/nvim/msgpack_rpc/channel.c
@@ -484,6 +484,16 @@ void rpc_close(Channel *channel)
}
channel->rpc.closed = true;
+
+ // Scheduled to avoid running UILeave autocommands in a libuv handler.
+ multiqueue_put(main_loop.fast_events, rpc_close_event, channel);
+}
+
+static void rpc_close_event(void **argv)
+{
+ Channel *channel = (Channel *)argv[0];
+ assert(channel);
+
channel_decref(channel);
bool is_ui_client = ui_client_channel_id && channel->id == ui_client_channel_id;