Bug 665733 – GDBusConnection holds lock while calling destroynotify
authorDavid Zeuthen <davidz@redhat.com>
Wed, 7 Dec 2011 15:25:24 +0000 (10:25 -0500)
committerDavid Zeuthen <davidz@redhat.com>
Wed, 7 Dec 2011 15:30:42 +0000 (10:30 -0500)
Fix this problem by always running the destroynotify from an idle.

https://bugzilla.gnome.org/show_bug.cgi?id=665733

Signed-off-by: David Zeuthen <davidz@redhat.com>
gio/gdbusconnection.c
gio/tests/gdbus-export.c

index 34368e2..36d7bfa 100644 (file)
@@ -260,38 +260,27 @@ call_destroy_notify (GMainContext  *context,
                      GDestroyNotify callback,
                      gpointer       user_data)
 {
-  GMainContext *current_context;
+  GSource *idle_source;
+  CallDestroyNotifyData *data;
 
   if (callback == NULL)
     goto out;
 
-  current_context = g_main_context_get_thread_default ();
-  if ((context == current_context) ||
-      (current_context == NULL && context == g_main_context_default ()))
-    {
-      callback (user_data);
-    }
-  else
-    {
-      GSource *idle_source;
-      CallDestroyNotifyData *data;
-
-      data = g_new0 (CallDestroyNotifyData, 1);
-      data->callback = callback;
-      data->user_data = user_data;
-      data->context = context;
-      if (data->context != NULL)
-        g_main_context_ref (data->context);
-
-      idle_source = g_idle_source_new ();
-      g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);
-      g_source_set_callback (idle_source,
-                             call_destroy_notify_data_in_idle,
-                             data,
-                             (GDestroyNotify) call_destroy_notify_data_free);
-      g_source_attach (idle_source, data->context);
-      g_source_unref (idle_source);
-    }
+  data = g_new0 (CallDestroyNotifyData, 1);
+  data->callback = callback;
+  data->user_data = user_data;
+  data->context = context;
+  if (data->context != NULL)
+    g_main_context_ref (data->context);
+
+  idle_source = g_idle_source_new ();
+  g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);
+  g_source_set_callback (idle_source,
+                         call_destroy_notify_data_in_idle,
+                         data,
+                         (GDestroyNotify) call_destroy_notify_data_free);
+  g_source_attach (idle_source, data->context);
+  g_source_unref (idle_source);
 
  out:
   ;
index 424d031..21e9fda 100644 (file)
@@ -1093,6 +1093,7 @@ test_object_registration (void)
 
   /* unregister it via the id */
   g_assert (g_dbus_connection_unregister_object (c, registration_id));
+  g_main_context_iteration (NULL, FALSE);
   g_assert_cmpint (data.num_unregistered_calls, ==, 1);
   intern2_foo_reg_id = 0;
 
@@ -1148,6 +1149,7 @@ test_object_registration (void)
   /* unregister it, then register it again */
   g_assert_cmpint (data.num_unregistered_subtree_calls, ==, 0);
   g_assert (g_dbus_connection_unregister_subtree (c, subtree_registration_id));
+  g_main_context_iteration (NULL, FALSE);
   g_assert_cmpint (data.num_unregistered_subtree_calls, ==, 1);
   subtree_registration_id = g_dbus_connection_register_subtree (c,
                                                                 "/foo/boss/executives",
@@ -1346,6 +1348,7 @@ test_object_registration (void)
   /* check that unregistering the subtree handler works */
   g_assert_cmpint (data.num_unregistered_subtree_calls, ==, 1);
   g_assert (g_dbus_connection_unregister_subtree (c, subtree_registration_id));
+  g_main_context_iteration (NULL, FALSE);
   g_assert_cmpint (data.num_unregistered_subtree_calls, ==, 2);
   nodes = get_nodes_at (c, "/foo/boss/executives");
   g_assert (nodes != NULL);
@@ -1365,6 +1368,7 @@ test_object_registration (void)
   g_assert (g_dbus_connection_unregister_object (c, non_subtree_object_path_bar_reg_id));
   g_assert (g_dbus_connection_unregister_object (c, non_subtree_object_path_foo_reg_id));
 
+  g_main_context_iteration (NULL, FALSE);
   g_assert_cmpint (data.num_unregistered_calls, ==, num_successful_registrations);
 
   /* check that we no longer export any objects - TODO: it looks like there's a bug in