Permalink
Browse files

eloop: convert idle sources to hooks

Instead if implementing complex idle sources we now provide a hook so
other subsystems can register callbacks.

This simplifies the code a lot and doesn't drop any major functionality.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
  • Loading branch information...
1 parent 83ed40f commit 3219b9ccfd942b76eb5d632ad95eea2bc8a8059d @dvdhrm committed May 17, 2012
Showing with 49 additions and 152 deletions.
  1. +33 −136 src/eloop.c
  2. +1 −1 src/eloop.h
  3. +15 −15 src/terminal.c
View
@@ -56,10 +56,8 @@ struct ev_eloop {
unsigned long ref;
struct ev_fd *fd;
- struct ev_idle *idle_list;
- struct ev_idle *cur_idle;
-
struct kmscon_dlist sig_list;
+ struct kmscon_hook *idlers;
struct epoll_event *cur_fds;
size_t cur_fds_cnt;
@@ -102,16 +100,6 @@ struct ev_signal_shared {
struct kmscon_hook *hook;
};
-struct ev_idle {
- unsigned long ref;
- struct ev_eloop *loop;
- struct ev_idle *next;
- struct ev_idle *prev;
-
- ev_idle_cb cb;
- void *data;
-};
-
/*
* Shared signals
*/
@@ -260,10 +248,14 @@ int ev_eloop_new(struct ev_eloop **out)
loop->ref = 1;
kmscon_dlist_init(&loop->sig_list);
+ ret = kmscon_hook_new(&loop->idlers);
+ if (ret)
+ goto err_free;
+
loop->efd = epoll_create1(EPOLL_CLOEXEC);
if (loop->efd < 0) {
ret = -errno;
- goto err_free;
+ goto err_idlers;
}
ret = ev_fd_new(&loop->fd, loop->efd, EV_READABLE, eloop_event, loop);
@@ -276,6 +268,8 @@ int ev_eloop_new(struct ev_eloop **out)
err_close:
close(loop->efd);
+err_idlers:
+ kmscon_hook_free(loop->idlers);
err_free:
free(loop);
return ret;
@@ -307,6 +301,7 @@ void ev_eloop_unref(struct ev_eloop *loop)
ev_fd_unref(loop->fd);
close(loop->efd);
+ kmscon_hook_free(loop->idlers);
free(loop);
}
@@ -333,12 +328,7 @@ int ev_eloop_dispatch(struct ev_eloop *loop, int timeout)
return -EINVAL;
/* dispatch idle events */
- loop->cur_idle = loop->idle_list;
- while (loop->cur_idle) {
- loop->cur_idle->cb(loop->cur_idle, loop->cur_idle->data);
- if (loop->cur_idle)
- loop->cur_idle = loop->cur_idle->next;
- }
+ kmscon_hook_call(loop->idlers, loop, NULL);
/* dispatch fd events */
count = epoll_wait(loop->efd, ep, 32, timeout);
@@ -1018,124 +1008,9 @@ void ev_eloop_rm_counter(struct ev_counter *cnt)
}
/*
- * Idle sources
+ * Shared signals
*/
-int ev_idle_new(struct ev_idle **out)
-{
- struct ev_idle *idle;
-
- if (!out)
- return -EINVAL;
-
- idle = malloc(sizeof(*idle));
- if (!idle)
- return -ENOMEM;
-
- memset(idle, 0, sizeof(*idle));
- idle->ref = 1;
-
- *out = idle;
- return 0;
-}
-
-void ev_idle_ref(struct ev_idle *idle)
-{
- if (!idle)
- return;
-
- ++idle->ref;
-}
-
-void ev_idle_unref(struct ev_idle *idle)
-{
- if (!idle || !idle->ref || --idle->ref)
- return;
-
- free(idle);
-}
-
-int ev_eloop_new_idle(struct ev_eloop *loop, struct ev_idle **out,
- ev_idle_cb cb, void *data)
-{
- struct ev_idle *idle;
- int ret;
-
- if (!out || !loop || !cb)
- return -EINVAL;
-
- ret = ev_idle_new(&idle);
- if (ret)
- return ret;
-
- ret = ev_eloop_add_idle(loop, idle, cb, data);
- if (ret) {
- ev_idle_unref(idle);
- return ret;
- }
-
- ev_idle_unref(idle);
- *out = idle;
- return 0;
-}
-
-int ev_eloop_add_idle(struct ev_eloop *loop, struct ev_idle *idle,
- ev_idle_cb cb, void *data)
-{
- if (!loop || !idle || !cb)
- return -EINVAL;
-
- if (idle->next || idle->prev || idle->loop)
- return -EALREADY;
-
- idle->next = loop->idle_list;
- if (idle->next)
- idle->next->prev = idle;
- loop->idle_list = idle;
-
- idle->loop = loop;
- idle->cb = cb;
- idle->data = data;
-
- ev_idle_ref(idle);
- ev_eloop_ref(loop);
-
- return 0;
-}
-
-void ev_eloop_rm_idle(struct ev_idle *idle)
-{
- struct ev_eloop *loop;
-
- if (!idle || !idle->loop)
- return;
-
- loop = idle->loop;
-
- /*
- * If the loop is currently dispatching, we need to check whether we are
- * the current element and correctly set it to the next element.
- */
- if (loop->cur_idle == idle)
- loop->cur_idle = idle->next;
-
- if (idle->prev)
- idle->prev->next = idle->next;
- if (idle->next)
- idle->next->prev = idle->prev;
- if (loop->idle_list == idle)
- loop->idle_list = idle->next;
-
- idle->next = NULL;
- idle->prev = NULL;
- idle->loop = NULL;
- idle->cb = NULL;
- idle->data = NULL;
-
- ev_idle_unref(idle);
- ev_eloop_unref(loop);
-}
-
int ev_eloop_register_signal_cb(struct ev_eloop *loop, int signum,
ev_signal_shared_cb cb, void *data)
{
@@ -1180,3 +1055,25 @@ void ev_eloop_unregister_signal_cb(struct ev_eloop *loop, int signum,
}
}
}
+
+/*
+ * Idle sources
+ */
+
+int ev_eloop_register_idle_cb(struct ev_eloop *eloop, ev_idle_cb cb,
+ void *data)
+{
+ if (!eloop)
+ return -EINVAL;
+
+ return kmscon_hook_add_cast(eloop->idlers, cb, data);
+}
+
+void ev_eloop_unregister_idle_cb(struct ev_eloop *eloop, ev_idle_cb cb,
+ void *data)
+{
+ if (!eloop)
+ return;
+
+ kmscon_hook_rm_cast(eloop->idlers, cb, data);
+}
View
@@ -46,7 +46,7 @@ struct ev_fd;
struct ev_timer;
struct ev_counter;
-typedef void (*ev_idle_cb) (struct ev_idle *idle, void *data);
+typedef void (*ev_idle_cb) (struct ev_eloop *eloop, void *unused, void *data);
typedef void (*ev_fd_cb) (struct ev_fd *fd, int mask, void *data);
typedef void (*ev_signal_shared_cb)
(struct ev_eloop *eloop, struct signalfd_siginfo *info, void *data);
View
@@ -72,23 +72,24 @@ struct kmscon_terminal {
unsigned int max_width;
unsigned int max_height;
+ bool redraw;
struct kmscon_console *console;
- struct ev_idle *redraw;
struct kmscon_vte *vte;
struct kmscon_pty *pty;
kmscon_terminal_event_cb cb;
void *data;
};
-static void draw_all(struct ev_idle *idle, void *data)
+static void draw_all(struct ev_eloop *eloop, void *unused, void *data)
{
struct kmscon_terminal *term = data;
struct screen *iter;
struct uterm_screen *screen;
int ret;
- ev_eloop_rm_idle(idle);
+ ev_eloop_unregister_idle_cb(term->eloop, draw_all, term);
+ term->redraw = false;
iter = term->screens;
for (; iter; iter = iter->next) {
@@ -110,9 +111,14 @@ static void schedule_redraw(struct kmscon_terminal *term)
{
int ret;
- ret = ev_eloop_add_idle(term->eloop, term->redraw, draw_all, term);
- if (ret && ret != -EALREADY)
- log_warn("terminal: cannot schedule redraw");
+ if (term->redraw)
+ return;
+
+ ret = ev_eloop_register_idle_cb(term->eloop, draw_all, term);
+ if (ret)
+ log_warn("cannot schedule redraw");
+ else
+ term->redraw = true;
}
static int add_display(struct kmscon_terminal *term, struct uterm_display *disp)
@@ -275,13 +281,9 @@ int kmscon_terminal_new(struct kmscon_terminal **out,
term->video = video;
term->input = input;
- ret = ev_idle_new(&term->redraw);
- if (ret)
- goto err_free;
-
ret = kmscon_console_new(&term->console);
if (ret)
- goto err_idle;
+ goto err_free;
ret = kmscon_vte_new(&term->vte);
if (ret)
@@ -322,8 +324,6 @@ int kmscon_terminal_new(struct kmscon_terminal **out,
kmscon_vte_unref(term->vte);
err_con:
kmscon_console_unref(term->console);
-err_idle:
- ev_idle_unref(term->redraw);
err_free:
free(term);
return ret;
@@ -354,8 +354,8 @@ void kmscon_terminal_unref(struct kmscon_terminal *term)
kmscon_pty_unref(term->pty);
kmscon_vte_unref(term->vte);
kmscon_console_unref(term->console);
- ev_eloop_rm_idle(term->redraw);
- ev_idle_unref(term->redraw);
+ if (term->redraw)
+ ev_eloop_unregister_idle_cb(term->eloop, draw_all, term);
kmscon_input_unref(term->input);
uterm_video_unref(term->video);
ev_eloop_unref(term->eloop);

0 comments on commit 3219b9c

Please sign in to comment.