From bdfc516715201ab934e2a166acf9a1265aafa4be Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Sun, 5 Dec 2010 16:46:48 -0500 Subject: [PATCH] StTextureCache: Plug leaks in tiled image loading We weren't freeing the whole pixbuf, nor were we the GList of subpixbufs. Plug both of these leaks in the error handling path and in the default case. All of the unreffing/cleanup should happen in the GDestroyNotify for the result, not some in the handler. https://bugzilla.gnome.org/show_bug.cgi?id=636489 --- src/st/st-texture-cache.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/st/st-texture-cache.c b/src/st/st-texture-cache.c index 35931da36..520b7d750 100644 --- a/src/st/st-texture-cache.c +++ b/src/st/st-texture-cache.c @@ -1183,9 +1183,7 @@ on_sliced_image_loaded (GObject *source_object, { ClutterActor *actor = load_from_pixbuf (GDK_PIXBUF (list->data)); clutter_actor_hide (actor); - clutter_container_add_actor (CLUTTER_CONTAINER (data->group), actor); - g_object_unref (list->data); } } @@ -1198,6 +1196,17 @@ on_data_destroy (gpointer data) g_free (d); } +static void +free_glist_unref_gobjects (gpointer p) +{ + GList *list = p; + GList *iter; + + for (iter = list; iter; iter = iter->next) + g_object_unref (iter->data); + g_list_free (list); +} + static void load_sliced_image (GSimpleAsyncResult *result, GObject *object, @@ -1223,17 +1232,14 @@ load_sliced_image (GSimpleAsyncResult *result, for (x = 0; x < width; x += data->grid_height) { GdkPixbuf *pixbuf = gdk_pixbuf_new_subpixbuf (pix, x, y, data->grid_width, data->grid_height); - if (!pixbuf) - { - g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, - "Has failed thumbnail"); - break; - } + g_assert (pixbuf != NULL); res = g_list_append (res, pixbuf); } } - if (res) - g_simple_async_result_set_op_res_gpointer (result, res, (GDestroyNotify)g_list_free); + /* We don't need the original pixbuf anymore, though the subpixbufs + will hold a reference. */ + g_object_unref (pix); + g_simple_async_result_set_op_res_gpointer (result, res, free_glist_unref_gobjects); } /**