aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/event/loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/event/loop.c')
-rw-r--r--src/nvim/event/loop.c95
1 files changed, 18 insertions, 77 deletions
diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c
index d90565002e..3d3288f858 100644
--- a/src/nvim/event/loop.c
+++ b/src/nvim/event/loop.c
@@ -1,3 +1,4 @@
+#include <stdarg.h>
#include <stdint.h>
#include <uv.h>
@@ -9,17 +10,23 @@
# include "event/loop.c.generated.h"
#endif
+typedef struct idle_event {
+ uv_idle_t idle;
+ Event event;
+} IdleEvent;
+
void loop_init(Loop *loop, void *data)
{
uv_loop_init(&loop->uv);
loop->uv.data = loop;
- loop->deferred_events = kl_init(Event);
- loop->immediate_events = kl_init(Event);
loop->children = kl_init(WatcherPtr);
loop->children_stop_requests = 0;
+ loop->events = queue_new_parent(loop_on_put, loop);
+ loop->fast_events = queue_new_child(loop->events);
uv_signal_init(&loop->uv, &loop->children_watcher);
uv_timer_init(&loop->uv, &loop->children_kill_timer);
+ uv_timer_init(&loop->uv, &loop->poll_timer);
}
void loop_poll_events(Loop *loop, int ms)
@@ -30,89 +37,36 @@ void loop_poll_events(Loop *loop, int ms)
abort(); // Should not re-enter uv_run
}
- bool wait = true;
- uv_timer_t timer;
+ uv_run_mode mode = UV_RUN_ONCE;
if (ms > 0) {
- uv_timer_init(&loop->uv, &timer);
// Use a repeating timeout of ms milliseconds to make sure
// we do not block indefinitely for I/O.
- uv_timer_start(&timer, timer_cb, (uint64_t)ms, (uint64_t)ms);
+ uv_timer_start(&loop->poll_timer, timer_cb, (uint64_t)ms, (uint64_t)ms);
} else if (ms == 0) {
// For ms == 0, we need to do a non-blocking event poll by
// setting the run mode to UV_RUN_NOWAIT.
- wait = false;
+ mode = UV_RUN_NOWAIT;
}
- if (wait) {
- loop_run_once(loop);
- } else {
- loop_run_nowait(loop);
- }
+ uv_run(&loop->uv, mode);
if (ms > 0) {
- // Ensure the timer handle is closed and run the event loop
- // once more to let libuv perform it's cleanup
- uv_timer_stop(&timer);
- uv_close((uv_handle_t *)&timer, NULL);
- loop_run_nowait(loop);
+ uv_timer_stop(&loop->poll_timer);
}
recursive--; // Can re-enter uv_run now
- process_events_from(loop->immediate_events);
-}
-
-bool loop_has_deferred_events(Loop *loop)
-{
- return loop->deferred_events_allowed && !kl_empty(loop->deferred_events);
+ queue_process_events(loop->fast_events);
}
-void loop_enable_deferred_events(Loop *loop)
-{
- ++loop->deferred_events_allowed;
-}
-
-void loop_disable_deferred_events(Loop *loop)
-{
- --loop->deferred_events_allowed;
-}
-
-// Queue an event
-void loop_push_event(Loop *loop, Event event, bool deferred)
+void loop_on_put(Queue *queue, void *data)
{
+ Loop *loop = data;
// Sometimes libuv will run pending callbacks(timer for example) before
// blocking for a poll. If this happens and the callback pushes a event to one
// of the queues, the event would only be processed after the poll
// returns(user hits a key for example). To avoid this scenario, we call
// uv_stop when a event is enqueued.
- loop_stop(loop);
- kl_push(Event, deferred ? loop->deferred_events : loop->immediate_events,
- event);
-}
-
-void loop_process_event(Loop *loop)
-{
- process_events_from(loop->deferred_events);
-}
-
-
-void loop_run(Loop *loop)
-{
- uv_run(&loop->uv, UV_RUN_DEFAULT);
-}
-
-void loop_run_once(Loop *loop)
-{
- uv_run(&loop->uv, UV_RUN_ONCE);
-}
-
-void loop_run_nowait(Loop *loop)
-{
- uv_run(&loop->uv, UV_RUN_NOWAIT);
-}
-
-void loop_stop(Loop *loop)
-{
uv_stop(&loop->uv);
}
@@ -120,25 +74,12 @@ void loop_close(Loop *loop)
{
uv_close((uv_handle_t *)&loop->children_watcher, NULL);
uv_close((uv_handle_t *)&loop->children_kill_timer, NULL);
+ uv_close((uv_handle_t *)&loop->poll_timer, NULL);
do {
uv_run(&loop->uv, UV_RUN_DEFAULT);
} while (uv_loop_close(&loop->uv));
}
-void loop_process_all_events(Loop *loop)
-{
- process_events_from(loop->immediate_events);
- process_events_from(loop->deferred_events);
-}
-
-static void process_events_from(klist_t(Event) *queue)
-{
- while (!kl_empty(queue)) {
- Event event = kl_shift(Event, queue);
- event.handler(event);
- }
-}
-
static void timer_cb(uv_timer_t *handle)
{
}