In GetItems, unref objects in two passes
authorMike Gorse <mgorse@novell.com>
Sat, 26 Nov 2011 21:50:55 +0000 (15:50 -0600)
committerMike Gorse <mgorse@novell.com>
Sat, 26 Nov 2011 21:50:55 +0000 (15:50 -0600)
It is dangerous to unref cache objects inside a g_hash_table_foreach,
since, if the object is finalized, it will be removed, which can cause
problems with the iterator. Instead, make a GSList of the objects to
unref, then use this GSList to unref.

atk-adaptor/adaptors/cache-adaptor.c

index 4f647a1..8bd49af 100644 (file)
@@ -234,9 +234,10 @@ append_accessible_hf (gpointer key, gpointer obj_data, gpointer data)
 }
 
 static void
-unref_accessible_hf (gpointer key, gpointer obj_data, gpointer data)
+add_to_list_hf (gpointer key, gpointer obj_data, gpointer data)
 {
-  g_object_unref (key);
+  GSList **listptr = data;
+  *listptr = g_slist_prepend (*listptr, key);
 }
 
 /*---------------------------------------------------------------------------*/
@@ -302,6 +303,7 @@ impl_GetItems (DBusConnection * bus, DBusMessage * message, void *user_data)
 {
   DBusMessage *reply;
   DBusMessageIter iter, iter_array;
+  GSList *pending_unrefs = NULL;
 
   if (bus == spi_global_app_data->bus)
     spi_atk_add_client (dbus_message_get_sender (message));
@@ -313,7 +315,8 @@ impl_GetItems (DBusConnection * bus, DBusMessage * message, void *user_data)
                                     SPI_CACHE_ITEM_SIGNATURE, &iter_array);
   spi_cache_foreach (spi_global_cache, ref_accessible_hf, NULL);
   spi_cache_foreach (spi_global_cache, append_accessible_hf, &iter_array);
-  spi_cache_foreach (spi_global_cache, unref_accessible_hf, NULL);
+  spi_cache_foreach (spi_global_cache, add_to_list_hf, &pending_unrefs);
+  g_slist_free_full (pending_unrefs, g_object_unref);
   dbus_message_iter_close_container (&iter, &iter_array);
   return reply;
 }