[clutter/wip/wayland: 3/45] cogland: Fix crash when frame callback is destroyed before emitted
- From: Robert Bragg <rbragg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/wip/wayland: 3/45] cogland: Fix crash when frame callback is destroyed before emitted
- Date: Wed, 22 Feb 2012 17:59:57 +0000 (UTC)
commit 5e0e53a66e44a49d03e4c420c69321af0d4a64ab
Author: Robert Bragg <robert linux intel com>
Date: Tue Jan 3 23:45:29 2012 +0000
cogland: Fix crash when frame callback is destroyed before emitted
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 instead stores the callbacks in a GQueue with embedded list nodes
so that they can be removed from the list in the resource destructor.
That way it doesn't matter how the resource is destroyed, it will still
get removed from the list.
This patch was based on an equivalent patch made to cogland by Neil
Roberts.
tests/interactive/test-wayland-surface.c | 24 +++++++++++++++++-------
1 files changed, 17 insertions(+), 7 deletions(-)
---
diff --git a/tests/interactive/test-wayland-surface.c b/tests/interactive/test-wayland-surface.c
index f8938f6..015e0e2 100644
--- a/tests/interactive/test-wayland-surface.c
+++ b/tests/interactive/test-wayland-surface.c
@@ -74,6 +74,12 @@ typedef struct
typedef struct
{
+ /* GList node used as an embedded list */
+ GList node;
+
+ /* Pointer back to the compositor */
+ TWSCompositor *compositor;
+
struct wl_resource resource;
} TWSFrameCallback;
@@ -86,7 +92,7 @@ struct _TWSCompositor
GList *outputs;
GSource *wayland_event_source;
GList *surfaces;
- GArray *frame_callbacks;
+ GQueue frame_callbacks;
int xwayland_display_index;
char *xwayland_lockfile;
@@ -324,6 +330,9 @@ 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);
}
@@ -336,6 +345,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;
@@ -343,7 +354,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 = {
@@ -466,18 +478,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
@@ -1029,7 +1039,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]