diff options
-rw-r--r-- | src/nvim/lib/klist.h | 35 | ||||
-rw-r--r-- | src/nvim/os/event.c | 7 |
2 files changed, 27 insertions, 15 deletions
diff --git a/src/nvim/lib/klist.h b/src/nvim/lib/klist.h index 7df809f07b..10d6846133 100644 --- a/src/nvim/lib/klist.h +++ b/src/nvim/lib/klist.h @@ -27,10 +27,12 @@ #define _AC_KLIST_H #include <stdlib.h> +#include <assert.h> #include "nvim/memory.h" #include "nvim/func_attr.h" + #define KMEMPOOL_INIT(name, kmptype_t, kmpfree_f) \ typedef struct { \ size_t cnt, n, max; \ @@ -95,23 +97,27 @@ kmp_free(name, kl->mp, p); \ kmp_free(name, kl->mp, p); \ kmp_destroy(name, kl->mp); \ - xfree(kl); \ + xfree(kl); \ } \ - static inline kltype_t *kl_pushp_##name(kl_##name##_t *kl) { \ + static inline void kl_push_##name(kl_##name##_t *kl, kltype_t d) { \ kl1_##name *q, *p = kmp_alloc(name, kl->mp); \ q = kl->tail; p->next = 0; kl->tail->next = p; kl->tail = p; \ ++kl->size; \ - return &q->data; \ + q->data = d; \ } \ - static inline int kl_shift_##name(kl_##name##_t *kl, kltype_t *d) { \ + static inline kltype_t kl_shift_at_##name(kl_##name##_t *kl, \ + kl1_##name **n) { \ + assert((*n)->next); \ kl1_##name *p; \ - if (kl->head->next == 0) return -1; \ --kl->size; \ - p = kl->head; kl->head = kl->head->next; \ - if (d) *d = p->data; \ + p = *n; \ + *n = (*n)->next; \ + if (p == kl->head) kl->head = *n; \ + kltype_t d = p->data; \ kmp_free(name, kl->mp, p); \ - return 0; \ - } + return d; \ + } \ + #define kliter_t(name) kl1_##name #define klist_t(name) kl_##name##_t @@ -122,7 +128,14 @@ #define kl_init(name) kl_init_##name() #define kl_destroy(name, kl) kl_destroy_##name(kl) -#define kl_pushp(name, kl) kl_pushp_##name(kl) -#define kl_shift(name, kl, d) kl_shift_##name(kl, d) +#define kl_push(name, kl, d) kl_push_##name(kl, d) +#define kl_shift_at(name, kl, node) kl_shift_at_##name(kl, node) +#define kl_shift(name, kl) kl_shift_at(name, kl, &kl->head) #define kl_empty(kl) ((kl)->size == 0) +// Iteration macros. It's ok to modify the list while iterating as long as a +// `break` statement is executed before the next iteration. +#define kl_iter(name, kl, p) kl_iter_at(name, kl, p, NULL) +#define kl_iter_at(name, kl, p, h) \ + for (kl1_##name *p = h ? h : kl->head; p != kl->tail; p = p->next) + #endif diff --git a/src/nvim/os/event.c b/src/nvim/os/event.c index 4c3a4581c3..56874b495d 100644 --- a/src/nvim/os/event.c +++ b/src/nvim/os/event.c @@ -149,7 +149,7 @@ void event_push(Event event, bool deferred) // returns(user hits a key for example). To avoid this scenario, we call // uv_stop when a event is enqueued. uv_stop(uv_default_loop()); - *kl_pushp(Event, deferred ? deferred_events : immediate_events) = event; + kl_push(Event, deferred ? deferred_events : immediate_events, event); } void event_process(void) @@ -159,9 +159,8 @@ void event_process(void) static void process_events_from(klist_t(Event) *queue) { - Event event; - - while (kl_shift(Event, queue, &event) == 0) { + while (!kl_empty(queue)) { + Event event = kl_shift(Event, queue); event.handler(event); } } |