[PATCH] event-loop: add wl_event_loop_has_idle() helper

David Herrmann dh.herrmann at googlemail.com
Sun Sep 9 07:02:45 PDT 2012

As event-loop uses epoll() as base object we can stick one event-loop into
another by retrieving the epoll-fd and watching for events on it. However,
the idle objects aren't based on file-descriptors so if one event-callback
adds a new idle-source, the possible parent event-loop isn't notified of
this and will probably go to sleep instead of calling
wl_event_loop_dispatch() again in the next dispatch-round.

This wl_event_loop_has_idle() helper can be used to avoid this starvation.
The parent event loop simply calls this before going to sleep. If it is
true, it sets the timeout to 0, calls its own events and then calls
wl_event_loop_dispatch() to dispatch the wayland-event-loop idlers.

We could also add an "eventfd(2)" file descriptor internally to the
event-loop and write to it, when an idle source is active, and read from
it when no idle-source is active, anymore. This guarantees, that this
eventfd is readable as long as an idle-source is registered. So the parent
event-loop is notified that the epoll-fd is readable.
However, on worst case this adds one syscall per idle-source registration
and one per idle-source execution which can be quite heavy if used
agressively. So the wl_event_loop_has_idle() approach is the less
aggressive solution to this.

This, of course, is only used when stacking an wl_display/event-loop
object into your own event loop. Weston doesn't need this but other
compositors might want to stick to their own event-loop implementation
instead of using "event-loop" for their whole application.

I used _Bool as I don't know whether stdbool.h is actually compatible with
all the X-headers and legacy stuff where wayland may be used.

Signed-off-by: David Herrmann <dh.herrmann at googlemail.com>
 src/event-loop.c     | 6 ++++++
 src/wayland-server.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/src/event-loop.c b/src/event-loop.c
index a839daf..d0603aa 100644
--- a/src/event-loop.c
+++ b/src/event-loop.c
@@ -424,3 +424,9 @@ wl_event_loop_get_fd(struct wl_event_loop *loop)
 	return loop->epoll_fd;
+wl_event_loop_has_idle(struct wl_event_loop *loop)
+	return !wl_list_empty(&loop->idle_list);
diff --git a/src/wayland-server.h b/src/wayland-server.h
index cd79801..83b6635 100644
--- a/src/wayland-server.h
+++ b/src/wayland-server.h
@@ -71,6 +71,7 @@ struct wl_event_source *wl_event_loop_add_idle(struct wl_event_loop *loop,
 					       wl_event_loop_idle_func_t func,
 					       void *data);
 int wl_event_loop_get_fd(struct wl_event_loop *loop);
+_Bool wl_event_loop_has_idle(struct wl_event_loop *loop);
 struct wl_client;
 struct wl_display;

More information about the wayland-devel mailing list