mirror of
https://github.com/neovim/neovim.git
synced 2025-10-15 14:26:07 +00:00
events: Refactor event_poll to use stack-allocated timer handles
This commit is contained in:
@@ -21,12 +21,16 @@
|
|||||||
#define _destroy_event(x) // do nothing
|
#define _destroy_event(x) // do nothing
|
||||||
KLIST_INIT(Event, Event, _destroy_event)
|
KLIST_INIT(Event, Event, _destroy_event)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool timed_out;
|
||||||
|
int32_t ms;
|
||||||
|
uv_timer_t *timer;
|
||||||
|
} TimerData;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "os/event.c.generated.h"
|
# include "os/event.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
static klist_t(Event) *event_queue;
|
static klist_t(Event) *event_queue;
|
||||||
static uv_timer_t timer;
|
|
||||||
static uv_prepare_t timer_prepare;
|
|
||||||
|
|
||||||
void event_init()
|
void event_init()
|
||||||
{
|
{
|
||||||
@@ -44,9 +48,6 @@ void event_init()
|
|||||||
channel_init();
|
channel_init();
|
||||||
// Servers
|
// Servers
|
||||||
server_init();
|
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()
|
void event_teardown()
|
||||||
@@ -59,7 +60,6 @@ void event_teardown()
|
|||||||
// Wait for some event
|
// Wait for some event
|
||||||
bool event_poll(int32_t ms)
|
bool event_poll(int32_t ms)
|
||||||
{
|
{
|
||||||
bool timed_out;
|
|
||||||
uv_run_mode run_mode = UV_RUN_ONCE;
|
uv_run_mode run_mode = UV_RUN_ONCE;
|
||||||
|
|
||||||
if (input_ready()) {
|
if (input_ready()) {
|
||||||
@@ -68,14 +68,20 @@ bool event_poll(int32_t ms)
|
|||||||
}
|
}
|
||||||
|
|
||||||
input_start();
|
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) {
|
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
|
// 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
|
// We only start the timer after the loop is running, for that we
|
||||||
// use a prepare handle(pass the interval as data to it)
|
// 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);
|
uv_prepare_start(&timer_prepare, timer_prepare_cb);
|
||||||
} else if (ms == 0) {
|
} else if (ms == 0) {
|
||||||
// For ms == 0, we need to do a non-blocking event poll by
|
// 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
|
!input_ready() && // we have no input
|
||||||
kl_empty(event_queue) && // no events are waiting to be processed
|
kl_empty(event_queue) && // no events are waiting to be processed
|
||||||
run_mode != UV_RUN_NOWAIT && // ms != 0
|
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();
|
input_stop();
|
||||||
|
|
||||||
if (ms > 0) {
|
if (ms > 0) {
|
||||||
// Stop the timer
|
// Ensure the timer-related handles are closed and run the event loop
|
||||||
uv_timer_stop(&timer);
|
// 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();
|
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
|
// Set a flag in the `event_poll` loop for signaling of a timeout
|
||||||
static void timer_cb(uv_timer_t *handle)
|
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)
|
static void timer_prepare_cb(uv_prepare_t *handle)
|
||||||
{
|
{
|
||||||
uv_timer_start(&timer, timer_cb, *(uint32_t *)timer_prepare.data, 0);
|
TimerData *data = handle->data;
|
||||||
uv_prepare_stop(&timer_prepare);
|
assert(data->ms > 0);
|
||||||
|
uv_timer_start(data->timer, timer_cb, (uint32_t)data->ms, 0);
|
||||||
|
uv_prepare_stop(handle);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user