[clutter/fosdem-2012: 3/6] cogland: Fix crash when frame callback is destroyed before emitted
- From: Neil Roberts <nroberts src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/fosdem-2012: 3/6] cogland: Fix crash when frame callback is destroyed before emitted
- Date: Fri, 6 Jan 2012 14:47:18 +0000 (UTC)
commit 96683d821fc36d5969fe38c604c071e5abd700b1
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]