[clutter/wip/neil/wayland-compositor: 4/4] test-wayland-surface: Fix crash when frame callback is destroyed



commit 55c13593b0ac62544d7ee0b40ea96030bdb2ae2f
Author: Neil Roberts <neil linux intel com>
Date:   Fri Dec 23 14:20:01 2011 +0000

    test-wayland-surface: Fix crash when frame callback is destroyed
    
    If a frame callback is destroyed before it is invoked then the struct
    would be freed but it would not be removed from the array of callbacks
    so when cogland later tried to emit the callback it would crash.
    
    This patch is based on similar changes to the Cogland example in Cogl:
    
    http://git.gnome.org/browse/cogl/commit/?id=9000f8330d1bf798bf7d2347e

 tests/interactive/test-wayland-surface.c |   33 +++++++++++++++++++----------
 1 files changed, 21 insertions(+), 12 deletions(-)
---
diff --git a/tests/interactive/test-wayland-surface.c b/tests/interactive/test-wayland-surface.c
index 6e61316..55b5bfb 100644
--- a/tests/interactive/test-wayland-surface.c
+++ b/tests/interactive/test-wayland-surface.c
@@ -72,11 +72,6 @@ typedef struct
   struct wl_event_loop *loop;
 } WaylandEventSource;
 
-typedef struct
-{
-  struct wl_resource resource;
-} TWSFrameCallback;
-
 struct _TWSCompositor
 {
   struct wl_display *wayland_display;
@@ -86,7 +81,7 @@ struct _TWSCompositor
   GList *outputs;
   GSource *wayland_event_source;
   GList *surfaces;
-  GArray *frame_callbacks;
+  GQueue frame_callbacks;
 
   int xwayland_display_index;
   char *xwayland_lockfile;
@@ -97,6 +92,17 @@ struct _TWSCompositor
   struct wl_resource *xserver_resource;
 };
 
+typedef struct
+{
+  /* GList node used as an embedded list */
+  GList node;
+
+  /* Pointer back to the compositor */
+  TWSCompositor *compositor;
+
+  struct wl_resource resource;
+} TWSFrameCallback;
+
 static guint32
 get_time (void)
 {
@@ -306,6 +312,8 @@ destroy_frame_callback (struct wl_resource *callback_resource)
 {
   TWSFrameCallback *callback = callback_resource->data;
 
+  g_queue_unlink (&callback->compositor->frame_callbacks,
+                  &callback->node);
   g_slice_free (TWSFrameCallback, callback);
 }
 
@@ -318,6 +326,8 @@ tws_surface_frame (struct wl_client *client,
   TWSSurface *surface = surface_resource->data;
 
   callback = g_slice_new0 (TWSFrameCallback);
+  callback->compositor = surface->compositor;
+  callback->node.data = callback;
   callback->resource.object.interface = &wl_callback_interface;
   callback->resource.object.id = callback_id;
   callback->resource.destroy = destroy_frame_callback;
@@ -325,7 +335,8 @@ tws_surface_frame (struct wl_client *client,
 
   wl_client_add_resource (client, &callback->resource);
 
-  g_array_append_val (surface->compositor->frame_callbacks, callback);
+  g_queue_push_tail_link (&surface->compositor->frame_callbacks,
+                          &callback->node);
 }
 
 const struct wl_surface_interface tws_surface_interface = {
@@ -447,18 +458,16 @@ static void
 paint_finished_cb (ClutterActor *self, void *user_data)
 {
   TWSCompositor *compositor = user_data;
-  int i;
 
-  for (i = 0; i < compositor->frame_callbacks->len; i++)
+  while (!g_queue_is_empty (&compositor->frame_callbacks))
     {
       TWSFrameCallback *callback =
-        g_array_index (compositor->frame_callbacks, TWSFrameCallback *, i);
+        g_queue_peek_head (&compositor->frame_callbacks);
 
       wl_resource_post_event (&callback->resource,
                               WL_CALLBACK_DONE, get_time ());
       wl_resource_destroy (&callback->resource, 0);
     }
-  g_array_set_size (compositor->frame_callbacks, 0);
 }
 
 static void
@@ -948,7 +957,7 @@ test_wayland_surface_main (int argc, char **argv)
   if (compositor.wayland_display == NULL)
     g_error ("failed to create wayland display");
 
-  compositor.frame_callbacks = g_array_new (FALSE, FALSE, sizeof (void *));
+  g_queue_init (&compositor.frame_callbacks);
 
   if (!wl_display_add_global (compositor.wayland_display,
                               &wl_compositor_interface,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]