diff options
| author | Justin M. Keyes <justinkz@gmail.com> | 2016-09-29 17:09:37 +0200 |
|---|---|---|
| committer | Justin M. Keyes <justinkz@gmail.com> | 2016-10-02 00:24:49 +0200 |
| commit | 6186df3562e33e92f04ed8c850204ceabc4746e1 (patch) | |
| tree | 90cc5779b0ba395e1b07069573ddb836a7d9de1f /src/nvim/event | |
| parent | c8b6ec2e6a8599203b4cff762f148f62464d9725 (diff) | |
| download | rneovim-6186df3562e33e92f04ed8c850204ceabc4746e1.tar.gz rneovim-6186df3562e33e92f04ed8c850204ceabc4746e1.tar.bz2 rneovim-6186df3562e33e92f04ed8c850204ceabc4746e1.zip | |
event/multiqueue.c: Rename "queue" to "multiqueue".
`lib/queue.h` implements a basic queue. `event/queue.c` implements
a specialized data structure on top of lib/queue.h; it is not a "normal"
queue.
Rename the specialized multi-level queue implemented in event/queue.c to
"multiqueue", to avoid confusion when reading the code.
Before this change one can eventually notice that "macros (uppercase
symbols) are for the normal queue, lowercase operations are for the
multi-level queue", but that is unnecessary friction for new developers
(or existing developers just visiting this part of the codebase).
Diffstat (limited to 'src/nvim/event')
| -rw-r--r-- | src/nvim/event/loop.c | 24 | ||||
| -rw-r--r-- | src/nvim/event/loop.h | 20 | ||||
| -rw-r--r-- | src/nvim/event/multiqueue.c (renamed from src/nvim/event/queue.c) | 127 | ||||
| -rw-r--r-- | src/nvim/event/multiqueue.h | 19 | ||||
| -rw-r--r-- | src/nvim/event/process.c | 11 | ||||
| -rw-r--r-- | src/nvim/event/process.h | 2 | ||||
| -rw-r--r-- | src/nvim/event/queue.h | 19 | ||||
| -rw-r--r-- | src/nvim/event/signal.h | 2 | ||||
| -rw-r--r-- | src/nvim/event/socket.h | 2 | ||||
| -rw-r--r-- | src/nvim/event/stream.h | 2 | ||||
| -rw-r--r-- | src/nvim/event/time.c | 2 | ||||
| -rw-r--r-- | src/nvim/event/time.h | 2 |
12 files changed, 117 insertions, 115 deletions
diff --git a/src/nvim/event/loop.c b/src/nvim/event/loop.c index a4c4e5ac9c..d562ac1ed3 100644 --- a/src/nvim/event/loop.c +++ b/src/nvim/event/loop.c @@ -18,9 +18,9 @@ void loop_init(Loop *loop, void *data) loop->uv.data = loop; 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); - loop->thread_events = queue_new_parent(NULL, NULL); + loop->events = multiqueue_new_parent(loop_on_put, loop); + loop->fast_events = multiqueue_new_child(loop->events); + loop->thread_events = multiqueue_new_parent(NULL, NULL); uv_mutex_init(&loop->mutex); uv_async_init(&loop->uv, &loop->async, async_cb); uv_signal_init(&loop->uv, &loop->children_watcher); @@ -53,19 +53,19 @@ void loop_poll_events(Loop *loop, int ms) } loop->recursive--; // Can re-enter uv_run now - queue_process_events(loop->fast_events); + multiqueue_process_events(loop->fast_events); } // Schedule an event from another thread void loop_schedule(Loop *loop, Event event) { uv_mutex_lock(&loop->mutex); - queue_put_event(loop->thread_events, event); + multiqueue_put_event(loop->thread_events, event); uv_async_send(&loop->async); uv_mutex_unlock(&loop->mutex); } -void loop_on_put(Queue *queue, void *data) +void loop_on_put(MultiQueue *queue, void *data) { Loop *loop = data; // Sometimes libuv will run pending callbacks(timer for example) before @@ -86,9 +86,9 @@ void loop_close(Loop *loop, bool wait) do { uv_run(&loop->uv, wait ? UV_RUN_DEFAULT : UV_RUN_NOWAIT); } while (uv_loop_close(&loop->uv) && wait); - queue_free(loop->fast_events); - queue_free(loop->thread_events); - queue_free(loop->events); + multiqueue_free(loop->fast_events); + multiqueue_free(loop->thread_events); + multiqueue_free(loop->events); kl_destroy(WatcherPtr, loop->children); } @@ -96,9 +96,9 @@ static void async_cb(uv_async_t *handle) { Loop *l = handle->loop->data; uv_mutex_lock(&l->mutex); - while (!queue_empty(l->thread_events)) { - Event ev = queue_get(l->thread_events); - queue_put_event(l->fast_events, ev); + while (!multiqueue_empty(l->thread_events)) { + Event ev = multiqueue_get(l->thread_events); + multiqueue_put_event(l->fast_events, ev); } uv_mutex_unlock(&l->mutex); } diff --git a/src/nvim/event/loop.h b/src/nvim/event/loop.h index 407aa4245f..e7d7bdd483 100644 --- a/src/nvim/event/loop.h +++ b/src/nvim/event/loop.h @@ -7,7 +7,7 @@ #include "nvim/lib/klist.h" #include "nvim/os/time.h" -#include "nvim/event/queue.h" +#include "nvim/event/multiqueue.h" typedef void * WatcherPtr; @@ -16,7 +16,7 @@ KLIST_INIT(WatcherPtr, WatcherPtr, _noop) typedef struct loop { uv_loop_t uv; - Queue *events, *fast_events, *thread_events; + MultiQueue *events, *fast_events, *thread_events; klist_t(WatcherPtr) *children; uv_signal_t children_watcher; uv_timer_t children_kill_timer, poll_timer; @@ -26,10 +26,10 @@ typedef struct loop { int recursive; } Loop; -#define CREATE_EVENT(queue, handler, argc, ...) \ +#define CREATE_EVENT(multiqueue, handler, argc, ...) \ do { \ - if (queue) { \ - queue_put((queue), (handler), argc, __VA_ARGS__); \ + if (multiqueue) { \ + multiqueue_put((multiqueue), (handler), argc, __VA_ARGS__); \ } else { \ void *argv[argc] = { __VA_ARGS__ }; \ (handler)(argv); \ @@ -37,12 +37,12 @@ typedef struct loop { } while (0) // Poll for events until a condition or timeout -#define LOOP_PROCESS_EVENTS_UNTIL(loop, queue, timeout, condition) \ +#define LOOP_PROCESS_EVENTS_UNTIL(loop, multiqueue, timeout, condition) \ do { \ int remaining = timeout; \ uint64_t before = (remaining > 0) ? os_hrtime() : 0; \ while (!(condition)) { \ - LOOP_PROCESS_EVENTS(loop, queue, remaining); \ + LOOP_PROCESS_EVENTS(loop, multiqueue, remaining); \ if (remaining == 0) { \ break; \ } else if (remaining > 0) { \ @@ -56,10 +56,10 @@ typedef struct loop { } \ } while (0) -#define LOOP_PROCESS_EVENTS(loop, queue, timeout) \ +#define LOOP_PROCESS_EVENTS(loop, multiqueue, timeout) \ do { \ - if (queue && !queue_empty(queue)) { \ - queue_process_events(queue); \ + if (multiqueue && !multiqueue_empty(multiqueue)) { \ + multiqueue_process_events(multiqueue); \ } else { \ loop_poll_events(loop, timeout); \ } \ diff --git a/src/nvim/event/queue.c b/src/nvim/event/multiqueue.c index ee224b0a25..7efdfc4cad 100644 --- a/src/nvim/event/queue.c +++ b/src/nvim/event/multiqueue.c @@ -1,5 +1,5 @@ -// Queue for selective async event processing. Instances of this queue support a -// parent/child relationship with the following properties: +// Multi-level queue for selective async event processing. Multiqueue supports +// a parent-child relationship with the following properties: // // - pushing a node to a child queue will push a corresponding link node to the // parent queue @@ -9,7 +9,7 @@ // in the parent queue // // These properties allow Nvim to organize and process events from different -// sources with a certain degree of control. Here's how the queue is used: +// sources with a certain degree of control. How the multiqueue is used: // // +----------------+ // | Main loop | @@ -26,7 +26,7 @@ // +-----------+ +-----------+ +---------+ +---------+ // // -// The lower boxes represents event emitters, each with its own private queue +// The lower boxes represent event emitters, each with its own private queue // having the event loop queue as the parent. // // When idle, the main loop spins the event loop which queues events from many @@ -50,51 +50,52 @@ #include <uv.h> -#include "nvim/event/queue.h" +#include "nvim/event/multiqueue.h" #include "nvim/memory.h" #include "nvim/os/time.h" -typedef struct queue_item QueueItem; -struct queue_item { +typedef struct multiqueue_item MultiQueueItem; +struct multiqueue_item { union { - Queue *queue; + MultiQueue *queue; struct { Event event; - QueueItem *parent; + MultiQueueItem *parent; } item; } data; - bool link; // this is just a link to a node in a child queue + bool link; // true: current item is just a link to a node in a child queue QUEUE node; }; -struct queue { - Queue *parent; +struct multiqueue { + MultiQueue *parent; QUEUE headtail; put_callback put_cb; void *data; }; #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "event/queue.c.generated.h" +# include "event/multiqueue.c.generated.h" #endif -static Event NILEVENT = {.handler = NULL, .argv = {NULL}}; +static Event NILEVENT = { .handler = NULL, .argv = {NULL} }; -Queue *queue_new_parent(put_callback put_cb, void *data) +MultiQueue *multiqueue_new_parent(put_callback put_cb, void *data) { - return queue_new(NULL, put_cb, data); + return multiqueue_new(NULL, put_cb, data); } -Queue *queue_new_child(Queue *parent) +MultiQueue *multiqueue_new_child(MultiQueue *parent) FUNC_ATTR_NONNULL_ALL { assert(!parent->parent); - return queue_new(parent, NULL, NULL); + return multiqueue_new(parent, NULL, NULL); } -static Queue *queue_new(Queue *parent, put_callback put_cb, void *data) +static MultiQueue *multiqueue_new(MultiQueue *parent, put_callback put_cb, + void *data) { - Queue *rv = xmalloc(sizeof(Queue)); + MultiQueue *rv = xmalloc(sizeof(MultiQueue)); QUEUE_INIT(&rv->headtail); rv->parent = parent; rv->put_cb = put_cb; @@ -102,13 +103,13 @@ static Queue *queue_new(Queue *parent, put_callback put_cb, void *data) return rv; } -void queue_free(Queue *queue) +void multiqueue_free(MultiQueue *this) { - assert(queue); - while (!QUEUE_EMPTY(&queue->headtail)) { - QUEUE *q = QUEUE_HEAD(&queue->headtail); - QueueItem *item = queue_node_data(q); - if (queue->parent) { + assert(this); + while (!QUEUE_EMPTY(&this->headtail)) { + QUEUE *q = QUEUE_HEAD(&this->headtail); + MultiQueueItem *item = multiqueue_node_data(q); + if (this->parent) { QUEUE_REMOVE(&item->data.item.parent->node); xfree(item->data.item.parent); } @@ -116,66 +117,66 @@ void queue_free(Queue *queue) xfree(item); } - xfree(queue); + xfree(this); } -Event queue_get(Queue *queue) +Event multiqueue_get(MultiQueue *this) { - return queue_empty(queue) ? NILEVENT : queue_remove(queue); + return multiqueue_empty(this) ? NILEVENT : multiqueue_remove(this); } -void queue_put_event(Queue *queue, Event event) +void multiqueue_put_event(MultiQueue *this, Event event) { - assert(queue); - queue_push(queue, event); - if (queue->parent && queue->parent->put_cb) { - queue->parent->put_cb(queue->parent, queue->parent->data); + assert(this); + multiqueue_push(this, event); + if (this->parent && this->parent->put_cb) { + this->parent->put_cb(this->parent, this->parent->data); } } -void queue_process_events(Queue *queue) +void multiqueue_process_events(MultiQueue *this) { - assert(queue); - while (!queue_empty(queue)) { - Event event = queue_get(queue); + assert(this); + while (!multiqueue_empty(this)) { + Event event = multiqueue_get(this); if (event.handler) { event.handler(event.argv); } } } -bool queue_empty(Queue *queue) +bool multiqueue_empty(MultiQueue *this) { - assert(queue); - return QUEUE_EMPTY(&queue->headtail); + assert(this); + return QUEUE_EMPTY(&this->headtail); } -void queue_replace_parent(Queue *queue, Queue *new_parent) +void multiqueue_replace_parent(MultiQueue *this, MultiQueue *new_parent) { - assert(queue_empty(queue)); - queue->parent = new_parent; + assert(multiqueue_empty(this)); + this->parent = new_parent; } -static Event queue_remove(Queue *queue) +static Event multiqueue_remove(MultiQueue *this) { - assert(!queue_empty(queue)); - QUEUE *h = QUEUE_HEAD(&queue->headtail); + assert(!multiqueue_empty(this)); + QUEUE *h = QUEUE_HEAD(&this->headtail); QUEUE_REMOVE(h); - QueueItem *item = queue_node_data(h); + MultiQueueItem *item = multiqueue_node_data(h); Event rv; if (item->link) { - assert(!queue->parent); + assert(!this->parent); // remove the next node in the linked queue - Queue *linked = item->data.queue; - assert(!queue_empty(linked)); - QueueItem *child = - queue_node_data(QUEUE_HEAD(&linked->headtail)); + MultiQueue *linked = item->data.queue; + assert(!multiqueue_empty(linked)); + MultiQueueItem *child = + multiqueue_node_data(QUEUE_HEAD(&linked->headtail)); QUEUE_REMOVE(&child->node); rv = child->data.item.event; xfree(child); } else { - if (queue->parent) { + if (this->parent) { // remove the corresponding link node in the parent queue QUEUE_REMOVE(&item->data.item.parent->node); xfree(item->data.item.parent); @@ -187,22 +188,22 @@ static Event queue_remove(Queue *queue) return rv; } -static void queue_push(Queue *queue, Event event) +static void multiqueue_push(MultiQueue *this, Event event) { - QueueItem *item = xmalloc(sizeof(QueueItem)); + MultiQueueItem *item = xmalloc(sizeof(MultiQueueItem)); item->link = false; item->data.item.event = event; - QUEUE_INSERT_TAIL(&queue->headtail, &item->node); - if (queue->parent) { + QUEUE_INSERT_TAIL(&this->headtail, &item->node); + if (this->parent) { // push link node to the parent queue - item->data.item.parent = xmalloc(sizeof(QueueItem)); + item->data.item.parent = xmalloc(sizeof(MultiQueueItem)); item->data.item.parent->link = true; - item->data.item.parent->data.queue = queue; - QUEUE_INSERT_TAIL(&queue->parent->headtail, &item->data.item.parent->node); + item->data.item.parent->data.queue = this; + QUEUE_INSERT_TAIL(&this->parent->headtail, &item->data.item.parent->node); } } -static QueueItem *queue_node_data(QUEUE *q) +static MultiQueueItem *multiqueue_node_data(QUEUE *q) { - return QUEUE_DATA(q, QueueItem, node); + return QUEUE_DATA(q, MultiQueueItem, node); } diff --git a/src/nvim/event/multiqueue.h b/src/nvim/event/multiqueue.h new file mode 100644 index 0000000000..def6b95a10 --- /dev/null +++ b/src/nvim/event/multiqueue.h @@ -0,0 +1,19 @@ +#ifndef NVIM_EVENT_MULTIQUEUE_H +#define NVIM_EVENT_MULTIQUEUE_H + +#include <uv.h> + +#include "nvim/event/defs.h" +#include "nvim/lib/queue.h" + +typedef struct multiqueue MultiQueue; +typedef void (*put_callback)(MultiQueue *multiq, void *data); + +#define multiqueue_put(q, h, ...) \ + multiqueue_put_event(q, event_create(1, h, __VA_ARGS__)); + + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "event/multiqueue.h.generated.h" +#endif +#endif // NVIM_EVENT_MULTIQUEUE_H diff --git a/src/nvim/event/process.c b/src/nvim/event/process.c index 51f20b7eac..39dd5fd55a 100644 --- a/src/nvim/event/process.c +++ b/src/nvim/event/process.c @@ -126,7 +126,7 @@ void process_teardown(Loop *loop) FUNC_ATTR_NONNULL_ALL // Wait until all children exit and all close events are processed. LOOP_PROCESS_EVENTS_UNTIL( loop, loop->events, -1, - kl_empty(loop->children) && queue_empty(loop->events)); + kl_empty(loop->children) && multiqueue_empty(loop->events)); pty_process_teardown(loop); } @@ -163,7 +163,8 @@ void process_close_err(Process *proc) FUNC_ATTR_NONNULL_ALL /// indistinguishable from the process returning -1 by itself. Which /// is possible on some OS. Returns -2 if an user has interruped the /// wait. -int process_wait(Process *proc, int ms, Queue *events) FUNC_ATTR_NONNULL_ARG(1) +int process_wait(Process *proc, int ms, MultiQueue *events) + FUNC_ATTR_NONNULL_ARG(1) { // The default status is -1, which represents a timeout int status = -1; @@ -208,7 +209,7 @@ int process_wait(Process *proc, int ms, Queue *events) FUNC_ATTR_NONNULL_ARG(1) decref(proc); if (events) { // the decref call created an exit event, process it now - queue_process_events(events); + multiqueue_process_events(events); } } else { proc->refcount--; @@ -362,7 +363,7 @@ static void flush_stream(Process *proc, Stream *stream) // Poll for data and process the generated events. loop_poll_events(proc->loop, 0); if (proc->events) { - queue_process_events(proc->events); + multiqueue_process_events(proc->events); } // Stream can be closed if it is empty. @@ -402,7 +403,7 @@ static void on_process_exit(Process *proc) // OS. We are still in the libuv loop, so we cannot call code that polls for // more data directly. Instead delay the reading after the libuv loop by // queueing process_close_handles() as an event. - Queue *queue = proc->events ? proc->events : loop->events; + MultiQueue *queue = proc->events ? proc->events : loop->events; CREATE_EVENT(queue, process_close_handles, 1, proc); } diff --git a/src/nvim/event/process.h b/src/nvim/event/process.h index a4c6e7eeb2..5cbf7f9ce7 100644 --- a/src/nvim/event/process.h +++ b/src/nvim/event/process.h @@ -27,7 +27,7 @@ struct process { process_exit_cb cb; internal_process_cb internal_exit_cb, internal_close_cb; bool closed, term_sent, detach; - Queue *events; + MultiQueue *events; }; static inline Process process_init(Loop *loop, ProcessType type, void *data) diff --git a/src/nvim/event/queue.h b/src/nvim/event/queue.h deleted file mode 100644 index 85fc59f8b2..0000000000 --- a/src/nvim/event/queue.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef NVIM_EVENT_QUEUE_H -#define NVIM_EVENT_QUEUE_H - -#include <uv.h> - -#include "nvim/event/defs.h" -#include "nvim/lib/queue.h" - -typedef struct queue Queue; -typedef void (*put_callback)(Queue *queue, void *data); - -#define queue_put(q, h, ...) \ - queue_put_event(q, event_create(1, h, __VA_ARGS__)); - - -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "event/queue.h.generated.h" -#endif -#endif // NVIM_EVENT_QUEUE_H diff --git a/src/nvim/event/signal.h b/src/nvim/event/signal.h index e32608acc0..7fe352edef 100644 --- a/src/nvim/event/signal.h +++ b/src/nvim/event/signal.h @@ -14,7 +14,7 @@ struct signal_watcher { void *data; signal_cb cb; signal_close_cb close_cb; - Queue *events; + MultiQueue *events; }; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/event/socket.h b/src/nvim/event/socket.h index ad59fdbe3a..eb0823c76d 100644 --- a/src/nvim/event/socket.h +++ b/src/nvim/event/socket.h @@ -30,7 +30,7 @@ struct socket_watcher { void *data; socket_cb cb; socket_close_cb close_cb; - Queue *events; + MultiQueue *events; }; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/event/stream.h b/src/nvim/event/stream.h index a176fac1c0..d27497e4a4 100644 --- a/src/nvim/event/stream.h +++ b/src/nvim/event/stream.h @@ -53,7 +53,7 @@ struct stream { size_t pending_reqs; size_t num_bytes; bool closed; - Queue *events; + MultiQueue *events; }; #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/event/time.c b/src/nvim/event/time.c index f68a66345f..77260546db 100644 --- a/src/nvim/event/time.c +++ b/src/nvim/event/time.c @@ -51,7 +51,7 @@ static void time_watcher_cb(uv_timer_t *handle) FUNC_ATTR_NONNULL_ALL { TimeWatcher *watcher = handle->data; - if (watcher->blockable && !queue_empty(watcher->events)) { + if (watcher->blockable && !multiqueue_empty(watcher->events)) { // the timer blocked and there already is an unprocessed event waiting return; } diff --git a/src/nvim/event/time.h b/src/nvim/event/time.h index 14df176ea3..a6de89ad6e 100644 --- a/src/nvim/event/time.h +++ b/src/nvim/event/time.h @@ -12,7 +12,7 @@ struct time_watcher { uv_timer_t uv; void *data; time_cb cb, close_cb; - Queue *events; + MultiQueue *events; bool blockable; }; |