summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Roberts <neil@linux.intel.com>2011-12-23 14:20:01 +0000
committerNeil Roberts <neil@linux.intel.com>2011-12-23 14:20:01 +0000
commit55c13593b0ac62544d7ee0b40ea96030bdb2ae2f (patch)
tree45925979e6763015b0e3d909d07c28b9c06f4c3f
parent9855f063f2c122bbc215212733c7867be60542e9 (diff)
downloadclutter-wip/neil/wayland-compositor.tar.gz
test-wayland-surface: Fix crash when frame callback is destroyedwip/neil/wayland-compositor
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
-rw-r--r--tests/interactive/test-wayland-surface.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/tests/interactive/test-wayland-surface.c b/tests/interactive/test-wayland-surface.c
index 6e6131632..55b5bfb77 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,