diff options
author | Felipe Oliveira Carvalho <felipekde@gmail.com> | 2014-04-05 23:37:39 -0300 |
---|---|---|
committer | Thiago de Arruda <tpadilha84@gmail.com> | 2014-04-07 00:22:01 -0300 |
commit | 967fb1aca6ea9c3d3046ccd6b9fcf0f88d6999ac (patch) | |
tree | 886a553c1f5ea139fec7600803562aa11edcfe2a | |
parent | fac85c17248ab8c371fb311c1dd4bc1b2a7520cf (diff) | |
download | rneovim-967fb1aca6ea9c3d3046ccd6b9fcf0f88d6999ac.tar.gz rneovim-967fb1aca6ea9c3d3046ccd6b9fcf0f88d6999ac.tar.bz2 rneovim-967fb1aca6ea9c3d3046ccd6b9fcf0f88d6999ac.zip |
Reimplement the event queue in event.c using klist.h
- Add a new macro to klist.h: kl_empty()
The whole point of abstract data structures is to avoid reimplementing
common actions. The emptiness test seems to be such an action.
- Add a new function attribute to func_attr.h: FUNC_ATTR_UNUSED
Some of the many functions created by the macros in klist.h may end up not
being used. Unused functions cause compilation errors as we compile with
-Werror. To mark those functions as possibly unused we can use the
FUNC_ATTR_UNUSED now.
- Pass `Event` by value
`Event` is such a small struct that I don't think we should allocate heap space
and pass it by reference. Let's use the stack and memory cache in our favor
passing it by value.
-rw-r--r-- | src/func_attr.h | 5 | ||||
-rw-r--r-- | src/lib/klist.h | 5 | ||||
-rw-r--r-- | src/os/event.c | 50 | ||||
-rw-r--r-- | src/os/event.h | 2 | ||||
-rw-r--r-- | src/os/signal.c | 18 | ||||
-rw-r--r-- | src/os/signal.h | 2 |
6 files changed, 34 insertions, 48 deletions
diff --git a/src/func_attr.h b/src/func_attr.h index 94bab79a97..4275d23ff1 100644 --- a/src/func_attr.h +++ b/src/func_attr.h @@ -34,6 +34,7 @@ #define FUNC_ATTR_CONST __attribute__((const)) #define FUNC_ATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) #define FUNC_ATTR_ALWAYS_INLINE __attribute__((always_inline)) + #define FUNC_ATTR_UNUSED __attribute__((unused)) #ifdef __clang__ // clang only @@ -90,6 +91,10 @@ #define FUNC_ATTR_ALWAYS_INLINE #endif +#ifndef FUNC_ATTR_UNUSED + #define FUNC_ATTR_UNUSED +#endif + #ifndef FUNC_ATTR_NONNULL_ALL #define FUNC_ATTR_NONNULL_ALL #endif diff --git a/src/lib/klist.h b/src/lib/klist.h index bb60449915..f8b16ea9fa 100644 --- a/src/lib/klist.h +++ b/src/lib/klist.h @@ -26,8 +26,10 @@ #ifndef _AC_KLIST_H #define _AC_KLIST_H +#include <stdbool.h> #include <stdlib.h> +#include "func_attr.h" #include "memory.h" #define KMEMPOOL_INIT(name, kmptype_t, kmpfree_f) \ @@ -84,6 +86,8 @@ kl->head->next = 0; \ return kl; \ } \ + static inline void kl_destroy_##name(kl_##name##_t *kl) \ + FUNC_ATTR_UNUSED; \ static inline void kl_destroy_##name(kl_##name##_t *kl) { \ kl1_##name *p; \ for (p = kl->head; p != kl->tail; p = p->next) \ @@ -119,5 +123,6 @@ #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_empty(kl) ((kl)->size == 0) #endif diff --git a/src/os/event.c b/src/os/event.c index fe06ff4581..dd8d6d9bdd 100644 --- a/src/os/event.c +++ b/src/os/event.c @@ -4,6 +4,7 @@ #include <uv.h> +#include "lib/klist.h" #include "os/event.h" #include "os/input.h" #include "os/signal.h" @@ -11,22 +12,22 @@ #include "memory.h" #include "misc2.h" -typedef struct EventNode { - Event *event; - struct EventNode *next; -} EventNode; +// event.data will be cleaned up after the event is processed +#define _destroy_event(x) // do nothing +KLIST_INIT(Event, Event, _destroy_event) -static EventNode *head, *tail; +static klist_t(Event) *event_queue; static uv_timer_t timer; static uv_prepare_t timer_prepare; static bool poll_uv_loop(int ms); static void process_all_events(void); -static bool has_pending_events(void); static void timer_cb(uv_timer_t *handle, int); static void timer_prepare_cb(uv_prepare_t *, int); void event_init() { + // Initialize the event queue + event_queue = kl_init(Event); // Initialize input events input_init(); // Timer to wake the event loop if a timeout argument is passed to @@ -72,50 +73,27 @@ bool event_poll(int32_t ms) } // Push an event to the queue -void event_push(Event *event) +void event_push(Event event) { - EventNode *node = (EventNode *)xmalloc(sizeof(EventNode)); - node->event = event; - node->next = NULL; - - if (head == NULL) { - head = node; - } else { - tail->next = node; - } - - tail = node; + *kl_pushp(Event, event_queue) = event; } // Runs the appropriate action for each queued event static void process_all_events() { - EventNode *next; - Event *event; + Event event; - while (has_pending_events()) { - next = head->next; - event = head->event; - free(head); - head = next; - - switch (event->type) { + while (kl_shift(Event, event_queue, &event) == 0) { + switch (event.type) { case kEventSignal: signal_handle(event); break; default: abort(); } - } } -// Checks if there are queued events -bool has_pending_events() -{ - return head != NULL; -} - // Wait for some event static bool poll_uv_loop(int32_t ms) { @@ -150,7 +128,7 @@ static bool poll_uv_loop(int32_t ms) } while ( // Continue running if ... !input_ready() && // we have no input - !has_pending_events() && // 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 !timed_out // we didn't get a timeout ); @@ -162,7 +140,7 @@ static bool poll_uv_loop(int32_t ms) uv_timer_stop(&timer); } - return input_ready() || has_pending_events(); + return input_ready() || !kl_empty(event_queue); } // Set a flag in the `event_poll` loop for signaling of a timeout diff --git a/src/os/event.h b/src/os/event.h index fe846695e5..2470add1cf 100644 --- a/src/os/event.h +++ b/src/os/event.h @@ -15,7 +15,7 @@ typedef struct { void event_init(void); bool event_poll(int32_t ms); -void event_push(Event *event); +void event_push(Event event); #endif // NEOVIM_OS_EVENT_H diff --git a/src/os/signal.c b/src/os/signal.c index 2ac31060aa..503269208d 100644 --- a/src/os/signal.c +++ b/src/os/signal.c @@ -67,12 +67,11 @@ void signal_accept_deadly() rejecting_deadly = false; } -void signal_handle(Event *event) +void signal_handle(Event event) { - int signum = *(int *)event->data; + int signum = *(int *)event.data; - free(event->data); - free(event); + free(event.data); switch (signum) { case SIGINT: @@ -148,8 +147,6 @@ static void deadly_signal(int signum) static void signal_cb(uv_signal_t *handle, int signum) { - Event *event; - if (rejecting_deadly) { if (signum == SIGINT) { got_int = true; @@ -158,9 +155,10 @@ static void signal_cb(uv_signal_t *handle, int signum) return; } - event = (Event *)xmalloc(sizeof(Event)); - event->type = kEventSignal; - event->data = xmalloc(sizeof(int)); - *(int *)event->data = signum; + Event event = { + .type = kEventSignal, + .data = xmalloc(sizeof(int)) + }; + *(int *)event.data = signum; event_push(event); } diff --git a/src/os/signal.h b/src/os/signal.h index a5247742db..4507bea26b 100644 --- a/src/os/signal.h +++ b/src/os/signal.h @@ -7,7 +7,7 @@ void signal_init(void); void signal_stop(void); void signal_accept_deadly(void); void signal_reject_deadly(void); -void signal_handle(Event *event); +void signal_handle(Event event); #endif |