diff options
author | Thiago de Arruda <tpadilha84@gmail.com> | 2014-06-17 12:27:02 -0300 |
---|---|---|
committer | Thiago de Arruda <tpadilha84@gmail.com> | 2014-06-18 11:36:07 -0300 |
commit | 05bf7808e0fcd66a4fd3e4b2b1cd124e43534bee (patch) | |
tree | 1ce5c290f89b8bb376509dd618d6c5f5181052a5 /src | |
parent | 4cb5ce3c529b1e03b6c9f2733eec88a48173818f (diff) | |
download | rneovim-05bf7808e0fcd66a4fd3e4b2b1cd124e43534bee.tar.gz rneovim-05bf7808e0fcd66a4fd3e4b2b1cd124e43534bee.tar.bz2 rneovim-05bf7808e0fcd66a4fd3e4b2b1cd124e43534bee.zip |
events: Refactor event_poll to use stack-allocated timer handles
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/os/event.c | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/src/nvim/os/event.c b/src/nvim/os/event.c index 2ebf28f436..40ddf7097e 100644 --- a/src/nvim/os/event.c +++ b/src/nvim/os/event.c @@ -21,12 +21,16 @@ #define _destroy_event(x) // do nothing KLIST_INIT(Event, Event, _destroy_event) +typedef struct { + bool timed_out; + int32_t ms; + uv_timer_t *timer; +} TimerData; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "os/event.c.generated.h" #endif static klist_t(Event) *event_queue; -static uv_timer_t timer; -static uv_prepare_t timer_prepare; void event_init() { @@ -44,9 +48,6 @@ void event_init() channel_init(); // Servers server_init(); - uv_timer_init(uv_default_loop(), &timer); - // This prepare handle that actually starts the timer - uv_prepare_init(uv_default_loop(), &timer_prepare); } void event_teardown() @@ -59,7 +60,6 @@ void event_teardown() // Wait for some event bool event_poll(int32_t ms) { - bool timed_out; uv_run_mode run_mode = UV_RUN_ONCE; if (input_ready()) { @@ -68,14 +68,20 @@ bool event_poll(int32_t ms) } input_start(); - timed_out = false; + + uv_timer_t timer; + uv_prepare_t timer_prepare; + TimerData timer_data = {.ms = ms, .timed_out = false, .timer = &timer}; if (ms > 0) { + uv_timer_init(uv_default_loop(), &timer); + // This prepare handle that actually starts the timer + uv_prepare_init(uv_default_loop(), &timer_prepare); // Timeout passed as argument to the timer - timer.data = &timed_out; + timer.data = &timer_data; // We only start the timer after the loop is running, for that we // use a prepare handle(pass the interval as data to it) - timer_prepare.data = &ms; + timer_prepare.data = &timer_data; uv_prepare_start(&timer_prepare, timer_prepare_cb); } else if (ms == 0) { // For ms == 0, we need to do a non-blocking event poll by @@ -92,13 +98,17 @@ bool event_poll(int32_t ms) !input_ready() && // we have no input kl_empty(event_queue) && // no events are waiting to be processed run_mode != UV_RUN_NOWAIT && // ms != 0 - !timed_out); // we didn't get a timeout + !timer_data.timed_out); // we didn't get a timeout input_stop(); if (ms > 0) { - // Stop the timer - uv_timer_stop(&timer); + // Ensure the timer-related handles are closed and run the event loop + // once more to let libuv perform it's cleanup + uv_close((uv_handle_t *)&timer, NULL); + uv_close((uv_handle_t *)&timer_prepare, NULL); + uv_run(uv_default_loop(), UV_RUN_NOWAIT); + event_process(false); } return input_ready() || event_is_pending(); @@ -140,11 +150,14 @@ void event_process() // Set a flag in the `event_poll` loop for signaling of a timeout static void timer_cb(uv_timer_t *handle) { - *((bool *)handle->data) = true; + TimerData *data = handle->data; + data->timed_out = true; } static void timer_prepare_cb(uv_prepare_t *handle) { - uv_timer_start(&timer, timer_cb, *(uint32_t *)timer_prepare.data, 0); - uv_prepare_stop(&timer_prepare); + TimerData *data = handle->data; + assert(data->ms > 0); + uv_timer_start(data->timer, timer_cb, (uint32_t)data->ms, 0); + uv_prepare_stop(handle); } |