aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Oliveira Carvalho <felipekde@gmail.com>2014-04-05 23:37:39 -0300
committerThiago de Arruda <tpadilha84@gmail.com>2014-04-07 00:22:01 -0300
commit967fb1aca6ea9c3d3046ccd6b9fcf0f88d6999ac (patch)
tree886a553c1f5ea139fec7600803562aa11edcfe2a
parentfac85c17248ab8c371fb311c1dd4bc1b2a7520cf (diff)
downloadrneovim-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.h5
-rw-r--r--src/lib/klist.h5
-rw-r--r--src/os/event.c50
-rw-r--r--src/os/event.h2
-rw-r--r--src/os/signal.c18
-rw-r--r--src/os/signal.h2
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