event-loop: Fix idle handler dispatch corner case
authorKristian Høgsberg <krh@bitplanet.net>
Sat, 29 Oct 2011 18:27:33 +0000 (14:27 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Sat, 29 Oct 2011 18:27:33 +0000 (14:27 -0400)
When the last idle handler queues another idle handler, we fail to
dispatch that last handler.  The wl_list_for_each_safe loop looks up
the next pointer before running the handler, and at that point it points
to the head of the list and the loop terminates.

Instead, just loop until the list is empty.

src/event-loop.c

index 5bd52fd..de1863a 100644 (file)
@@ -434,9 +434,11 @@ post_dispatch_check(struct wl_event_loop *loop)
 static void
 dispatch_idle_sources(struct wl_event_loop *loop)
 {
-       struct wl_event_source_idle *source, *next;
+       struct wl_event_source_idle *source;
 
-       wl_list_for_each_safe(source, next, &loop->idle_list, base.link) {
+       while (!wl_list_empty(&loop->idle_list)) {
+               source = container_of(loop->idle_list.next,
+                                     struct wl_event_source_idle, base.link);
                source->func(source->base.data);
                wl_event_source_remove(&source->base);
        }