st-texture-cache: Plug some pixbuf refcount leaks on async operations

When extracting the sliced image, the GTask grants data ownership on
g_task_propagate_*, so the pixbuf list must be properly freed. On async
load, we just left a dangling reference when returning on the async
task.

https://bugzilla.gnome.org/show_bug.cgi?id=642652
This commit is contained in:
Carlos Garnacho 2017-04-07 11:56:01 +02:00
parent cad5e06041
commit 44e80f4c46

View File

@ -448,6 +448,8 @@ load_pixbuf_thread (GTask *result,
g_task_return_error (result, error); g_task_return_error (result, error);
else if (pixbuf) else if (pixbuf)
g_task_return_pointer (result, g_object_ref (pixbuf), g_object_unref); g_task_return_pointer (result, g_object_ref (pixbuf), g_object_unref);
g_clear_object (&pixbuf);
} }
static GdkPixbuf * static GdkPixbuf *
@ -1038,18 +1040,22 @@ on_sliced_image_loaded (GObject *source_object,
GObject *cache = source_object; GObject *cache = source_object;
AsyncImageData *data = (AsyncImageData *)user_data; AsyncImageData *data = (AsyncImageData *)user_data;
GTask *task = G_TASK (res); GTask *task = G_TASK (res);
GList *list; GList *list, *pixbufs;
if (g_task_had_error (task)) if (g_task_had_error (task))
return; return;
for (list = g_task_propagate_pointer (task, NULL); list; list = list->next) pixbufs = g_task_propagate_pointer (task, NULL);
for (list = pixbufs; list; list = list->next)
{ {
ClutterActor *actor = load_from_pixbuf (GDK_PIXBUF (list->data)); ClutterActor *actor = load_from_pixbuf (GDK_PIXBUF (list->data));
clutter_actor_hide (actor); clutter_actor_hide (actor);
clutter_actor_add_child (data->actor, actor); clutter_actor_add_child (data->actor, actor);
} }
g_list_free_full (pixbufs, g_object_unref);
if (data->load_callback != NULL) if (data->load_callback != NULL)
data->load_callback (cache, data->load_callback_data); data->load_callback (cache, data->load_callback_data);
} }
@ -1057,12 +1063,7 @@ on_sliced_image_loaded (GObject *source_object,
static void static void
free_glist_unref_gobjects (gpointer p) free_glist_unref_gobjects (gpointer p)
{ {
GList *list = p; g_list_free_full (p, g_object_unref);
GList *iter;
for (iter = list; iter; iter = iter->next)
g_object_unref (iter->data);
g_list_free (list);
} }
static void static void