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.herrm...@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_EXPORT _Bool +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; -- 1.7.12 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel