From 0d2fe7786537ef63d0d3ed1e94546eb3ee35a368 Mon Sep 17 00:00:00 2001 From: bfredl Date: Sun, 23 Apr 2023 19:02:23 +0200 Subject: refactor(time): refactor delay with input checking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, there were three low-level delay entry points - os_delay(ms, ignoreinput=true): sleep for ms, only break on got_int - os_delay(ms, ignoreinput=false): sleep for ms, break on any key input os_microdelay(us, false): equivalent, but in μs (not directly called) - os_microdelay(us, true): sleep for μs, never break. The implementation of the latter two both used uv_cond_timedwait() This could have been for two reasons: 1. allow another thread to "interrupt" the wait 2. uv_cond_timedwait() has higher resolution than uv_sleep() However we (1) never used the first, even when TUI was a thread, and (2) nowhere in the codebase are we using μs resolution, it is always a ms multiplied with 1000. In addition, os_delay(ms, false) would completely block the thread for 100ms intervals and in between check for input. This is not how event handling is done alound here. Therefore: Replace the implementation of os_delay(ms, false) to use LOOP_PROCESS_EVENTS_UNTIL which does a proper epoll wait with a timeout, instead of the 100ms timer panic. Replace os_microdelay(us, false) with a direct wrapper of uv_sleep. --- src/nvim/os/input.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/nvim/os/input.c') diff --git a/src/nvim/os/input.c b/src/nvim/os/input.c index d472836d0a..e9f23eba40 100644 --- a/src/nvim/os/input.c +++ b/src/nvim/os/input.c @@ -441,7 +441,7 @@ bool input_blocking(void) // This is a replacement for the old `WaitForChar` function in os_unix.c static InbufPollResult inbuf_poll(int ms, MultiQueue *events) { - if (input_ready(events)) { + if (os_input_ready(events)) { return kInputAvail; } @@ -457,14 +457,14 @@ static InbufPollResult inbuf_poll(int ms, MultiQueue *events) DLOG("blocking... events_enabled=%d events_pending=%d", events != NULL, events && !multiqueue_empty(events)); LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, ms, - input_ready(events) || input_eof); + os_input_ready(events) || input_eof); blocking = false; if (do_profiling == PROF_YES && ms) { prof_inchar_exit(); } - if (input_ready(events)) { + if (os_input_ready(events)) { return kInputAvail; } return input_eof ? kInputEof : kInputNone; @@ -530,8 +530,8 @@ static int push_event_key(uint8_t *buf, int maxlen) return buf_idx; } -// Check if there's pending input -static bool input_ready(MultiQueue *events) +/// Check if there's pending input already in typebuf or `events` +bool os_input_ready(MultiQueue *events) { return (typebuf_was_filled // API call filled typeahead || rbuffer_size(input_buffer) // Input buffer filled -- cgit