diff options
author | Michael Schupikov <michael@schupikov.de> | 2016-12-26 18:30:10 +0100 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2017-01-06 00:57:31 +0100 |
commit | 23b39ebb24d6468d6dda76ffbb88f1fd3b99501c (patch) | |
tree | 0d7fb4dff30b34d8d936ecb7f89dd7bf91a1b5ac /src/nvim/os/time.c | |
parent | afa7f42f77f209d89fa3c84e5f627fbd2e536c4d (diff) | |
download | rneovim-23b39ebb24d6468d6dda76ffbb88f1fd3b99501c.tar.gz rneovim-23b39ebb24d6468d6dda76ffbb88f1fd3b99501c.tar.bz2 rneovim-23b39ebb24d6468d6dda76ffbb88f1fd3b99501c.zip |
time.c: os_microdelay(): Let input cancel the delay. #5830
Closes #5397
Diffstat (limited to 'src/nvim/os/time.c')
-rw-r--r-- | src/nvim/os/time.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/src/nvim/os/time.c b/src/nvim/os/time.c index 2205ad0958..8ce2ecf4f4 100644 --- a/src/nvim/os/time.c +++ b/src/nvim/os/time.c @@ -7,6 +7,7 @@ #include <uv.h> #include "nvim/os/time.h" +#include "nvim/os/input.h" #include "nvim/event/loop.h" #include "nvim/vim.h" #include "nvim/main.h" @@ -34,10 +35,10 @@ uint64_t os_hrtime(void) return uv_hrtime(); } -/// Sleeps for a certain amount of milliseconds +/// Sleeps for a certain amount of milliseconds. /// /// @param milliseconds Number of milliseconds to sleep -/// @param ignoreinput If true, allow a SIGINT to interrupt us +/// @param ignoreinput If true, only SIGINT (CTRL-C) can interrupt. void os_delay(uint64_t milliseconds, bool ignoreinput) { if (ignoreinput) { @@ -46,26 +47,42 @@ void os_delay(uint64_t milliseconds, bool ignoreinput) } LOOP_PROCESS_EVENTS_UNTIL(&main_loop, NULL, (int)milliseconds, got_int); } else { - os_microdelay(milliseconds * 1000); + os_microdelay(milliseconds * 1000u, ignoreinput); } } -/// Sleeps for a certain amount of microseconds +/// Sleeps for a certain amount of microseconds. /// -/// @param microseconds Number of microseconds to sleep -void os_microdelay(uint64_t microseconds) +/// @param ms Number of microseconds to sleep. +/// @param ignoreinput If true, ignore all input (including SIGINT/CTRL-C). +/// If false, waiting is aborted on any input. +void os_microdelay(uint64_t ms, bool ignoreinput) { - uint64_t elapsed = 0; - uint64_t ns = microseconds * 1000; // convert to nanoseconds + uint64_t elapsed = 0u; uint64_t base = uv_hrtime(); + // Convert microseconds to nanoseconds, or UINT64_MAX on overflow. + const uint64_t ns = (ms < UINT64_MAX / 1000u) ? ms * 1000u : UINT64_MAX; uv_mutex_lock(&delay_mutex); while (elapsed < ns) { - if (uv_cond_timedwait(&delay_cond, &delay_mutex, ns - elapsed) - == UV_ETIMEDOUT) + // If ignoring input, we simply wait the full delay. + // Else we check for input in ~100ms intervals. + const uint64_t ns_delta = ignoreinput + ? ns - elapsed + : MIN(ns - elapsed, 100000000u); // 100ms + + const int rv = uv_cond_timedwait(&delay_cond, &delay_mutex, ns_delta); + if (0 != rv && UV_ETIMEDOUT != rv) { + assert(false); + break; + } // Else: Timeout proceeded normally. + + if (!ignoreinput && os_char_avail()) { break; - uint64_t now = uv_hrtime(); + } + + const uint64_t now = uv_hrtime(); elapsed += now - base; base = now; } |