From cf318f710ea30010b739da9ef0d96a168ccbcf92 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sun, 9 Sep 2012 16:14:50 +0200 Subject: [PATCH] eloop: add post-dispatch hook When integrating other event-sources or event-loops into eloop which do not provide FD-abstractions, we often want to check for specific conditions before returning from the dispatch-callback or going to sleep. Therefore, you can now register a post-dispatch-cb and check whether your alien event source is firing. If it is, simply push an idle-source into the event-loop and it will fire during the next dispatch without going to sleep. Signed-off-by: David Herrmann --- src/eloop.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/eloop.h | 7 +++++++ 2 files changed, 59 insertions(+) diff --git a/src/eloop.c b/src/eloop.c index 503d269..edbe9ca 100644 --- a/src/eloop.c +++ b/src/eloop.c @@ -205,6 +205,7 @@ struct ev_eloop { struct kmscon_dlist sig_list; struct kmscon_hook *idlers; + struct kmscon_hook *posts; bool dispatching; struct epoll_event *cur_fds; @@ -761,6 +762,8 @@ int ev_eloop_dispatch(struct ev_eloop *loop, int timeout) } } + kmscon_hook_call(loop->posts, loop, NULL); + return 0; } @@ -2168,3 +2171,52 @@ void ev_eloop_unregister_idle_cb(struct ev_eloop *eloop, ev_idle_cb cb, if (!kmscon_hook_num(eloop->idlers)) ev_eloop_rm_counter(eloop->cnt); } + +/* + * Post-Dispatch Callbacks + * A post-dispatch cb is called whenever a single dispatch round is complete. + * You should avoid using them and instead not rely on any specific + * dispatch-behavior but expect every event to be recieved asynchronously. + * However, this hook is useful to integrate other limited APIs into this event + * loop if they do not provide proper FD-abstractions. + */ + +/** + * ev_eloop_register_post_cb: + * @eloop: event loop + * @cb: user-supplied callback + * @data: user-supplied data + * + * This register a new post-cb with the given callback and data. @cb must + * not be NULL!. + * + * Returns: 0 on success, negative error code on failure. + */ +int ev_eloop_register_post_cb(struct ev_eloop *eloop, ev_idle_cb cb, + void *data) +{ + if (!eloop) + return -EINVAL; + + return kmscon_hook_add_cast(eloop->posts, cb, data); +} + +/** + * ev_eloop_unregister_post_cb: + * @eloop: event loop + * @cb: user-supplied callback + * @data: user-supplied data + * + * This removes a post-cb. The arguments must be the same as for the + * ev_eloop_register_post_cb() call. If two identical callbacks are registered, + * then only one is removed. It doesn't matter which one is removed, because + * they are identical. + */ +void ev_eloop_unregister_post_cb(struct ev_eloop *eloop, ev_idle_cb cb, + void *data) +{ + if (!eloop) + return; + + kmscon_hook_rm_cast(eloop->idlers, cb, data); +} diff --git a/src/eloop.h b/src/eloop.h index ba45087..8a3642d 100644 --- a/src/eloop.h +++ b/src/eloop.h @@ -231,4 +231,11 @@ int ev_eloop_register_idle_cb(struct ev_eloop *eloop, ev_idle_cb cb, void ev_eloop_unregister_idle_cb(struct ev_eloop *eloop, ev_idle_cb cb, void *data); +/* post dispatch callbacks */ + +int ev_eloop_register_post_cb(struct ev_eloop *eloop, ev_idle_cb cb, + void *data); +void ev_eloop_unregister_post_cb(struct ev_eloop *eloop, ev_idle_cb cb, + void *data); + #endif /* EV_ELOOP_H */