desktop-shell: destroy surfaces in an idle handler after fade out
authorDerek Foreman <derekf@osg.samsung.com>
Tue, 14 Apr 2015 22:09:06 +0000 (17:09 -0500)
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>
Tue, 26 May 2015 10:07:58 +0000 (13:07 +0300)
It's possible for more than one animation to be taking place on a view at
the same time.  If one of those animations is the shell's fade out for
dying surfaces, its completion handler will trigger the surface destroy
signal, causing other animations on the animation list to remove themselves.

Since this removal occurs during the linked list walk, the compositor may
crash.

We move the actual surface destruction into an idle handler to avoid this.

Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Tested-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
desktop-shell/shell.c

index 452cd5fd07aab6e41050325b3cad814b770a8baa..8c37963a20075be13f47c38b40651e372b1cd9a1 100644 (file)
@@ -177,6 +177,8 @@ struct shell_surface {
        bool has_set_geometry, has_next_geometry;
 
        int focus_count;
+
+       bool destroying;
 };
 
 struct shell_grab {
@@ -3575,13 +3577,28 @@ shell_handle_surface_destroy(struct wl_listener *listener, void *data)
 }
 
 static void
-fade_out_done(struct weston_view_animation *animation, void *data)
+fade_out_done_idle_cb(void *data)
 {
        struct shell_surface *shsurf = data;
 
        weston_surface_destroy(shsurf->surface);
 }
 
+static void
+fade_out_done(struct weston_view_animation *animation, void *data)
+{
+       struct shell_surface *shsurf = data;
+       struct wl_event_loop *loop;
+
+       loop = wl_display_get_event_loop(
+                               shsurf->surface->compositor->wl_display);
+
+       if (!shsurf->destroying) {
+               wl_event_loop_add_idle(loop, fade_out_done_idle_cb, shsurf);
+               shsurf->destroying = true;
+       }
+}
+
 static void
 handle_resource_destroy(struct wl_listener *listener, void *data)
 {