diff options
| author | Gregory Anders <greg@gpanders.com> | 2025-03-07 12:16:39 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-07 12:16:39 -0600 |
| commit | 3d49c55d3c33a243f4236cf57b179608c288b145 (patch) | |
| tree | 506520f8fd41fe820ee039f18d9e8ea42d66356b /src/nvim/event | |
| parent | 8da59060c6dc9899d1f66d1c9b501b80496cc2e8 (diff) | |
| download | rneovim-3d49c55d3c33a243f4236cf57b179608c288b145.tar.gz rneovim-3d49c55d3c33a243f4236cf57b179608c288b145.tar.bz2 rneovim-3d49c55d3c33a243f4236cf57b179608c288b145.zip | |
fix(terminal): avoid rescheduling events onto the same queue (#32755)
Problem:
When a function like vim.wait() is used, we continuously drain the main
event queue until it is empty, never stopping for user input. This means
the libuv timer never runs and the terminal never gets refreshed, so
emit_termrequest continously reschedules itself onto the same event
queue, causing an infinite loop.
Solution:
Use a separate "pending" event queue, where events that require a
terminal refresh are temporarily placed. Drain this queue after a
terminal refresh and events are copied back onto the main queue. This
prevents infinite loops since the main event queue will always be able
to properly drain.
Diffstat (limited to 'src/nvim/event')
| -rw-r--r-- | src/nvim/event/loop.c | 5 | ||||
| -rw-r--r-- | src/nvim/event/multiqueue.c | 10 |
2 files changed, 11 insertions, 4 deletions
diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index 15d993cc62..f8b149ec78 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -212,10 +212,7 @@ static void async_cb(uv_async_t *handle) Loop *l = handle->loop->data; uv_mutex_lock(&l->mutex); // Flush thread_events to fast_events for processing on main loop. - while (!multiqueue_empty(l->thread_events)) { - Event ev = multiqueue_get(l->thread_events); - multiqueue_put_event(l->fast_events, ev); - } + multiqueue_move_events(l->fast_events, l->thread_events); uv_mutex_unlock(&l->mutex); } diff --git a/src/nvim/event/multiqueue.c b/src/nvim/event/multiqueue.c index 8646173776..5072bd774d 100644 --- a/src/nvim/event/multiqueue.c +++ b/src/nvim/event/multiqueue.c @@ -140,6 +140,16 @@ void multiqueue_put_event(MultiQueue *self, Event event) } } +/// Move events from src to dest. +void multiqueue_move_events(MultiQueue *dest, MultiQueue *src) + FUNC_ATTR_NONNULL_ALL +{ + while (!multiqueue_empty(src)) { + Event event = multiqueue_get(src); + multiqueue_put_event(dest, event); + } +} + void multiqueue_process_events(MultiQueue *self) { assert(self); |