Bug 665733 – GDBusConnection holds lock while calling destroynotify

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>
This commit is contained in:
David Zeuthen 2011-12-07 10:25:24 -05:00
parent 386bb0faad
commit 70dacf83d2
2 changed files with 20 additions and 27 deletions

View File

@ -260,38 +260,27 @@ call_destroy_notify (GMainContext *context,
GDestroyNotify callback, GDestroyNotify callback,
gpointer user_data) gpointer user_data)
{ {
GMainContext *current_context; GSource *idle_source;
CallDestroyNotifyData *data;
if (callback == NULL) if (callback == NULL)
goto out; goto out;
current_context = g_main_context_get_thread_default (); data = g_new0 (CallDestroyNotifyData, 1);
if ((context == current_context) || data->callback = callback;
(current_context == NULL && context == g_main_context_default ())) data->user_data = user_data;
{ data->context = context;
callback (user_data); if (data->context != NULL)
} g_main_context_ref (data->context);
else
{
GSource *idle_source;
CallDestroyNotifyData *data;
data = g_new0 (CallDestroyNotifyData, 1); idle_source = g_idle_source_new ();
data->callback = callback; g_source_set_priority (idle_source, G_PRIORITY_DEFAULT);
data->user_data = user_data; g_source_set_callback (idle_source,
data->context = context; call_destroy_notify_data_in_idle,
if (data->context != NULL) data,
g_main_context_ref (data->context); (GDestroyNotify) call_destroy_notify_data_free);
g_source_attach (idle_source, data->context);
idle_source = g_idle_source_new (); g_source_unref (idle_source);
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: out:
; ;

View File

@ -1093,6 +1093,7 @@ test_object_registration (void)
/* unregister it via the id */ /* unregister it via the id */
g_assert (g_dbus_connection_unregister_object (c, registration_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); g_assert_cmpint (data.num_unregistered_calls, ==, 1);
intern2_foo_reg_id = 0; intern2_foo_reg_id = 0;
@ -1148,6 +1149,7 @@ test_object_registration (void)
/* unregister it, then register it again */ /* unregister it, then register it again */
g_assert_cmpint (data.num_unregistered_subtree_calls, ==, 0); g_assert_cmpint (data.num_unregistered_subtree_calls, ==, 0);
g_assert (g_dbus_connection_unregister_subtree (c, subtree_registration_id)); 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); g_assert_cmpint (data.num_unregistered_subtree_calls, ==, 1);
subtree_registration_id = g_dbus_connection_register_subtree (c, subtree_registration_id = g_dbus_connection_register_subtree (c,
"/foo/boss/executives", "/foo/boss/executives",
@ -1346,6 +1348,7 @@ test_object_registration (void)
/* check that unregistering the subtree handler works */ /* check that unregistering the subtree handler works */
g_assert_cmpint (data.num_unregistered_subtree_calls, ==, 1); g_assert_cmpint (data.num_unregistered_subtree_calls, ==, 1);
g_assert (g_dbus_connection_unregister_subtree (c, subtree_registration_id)); 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); g_assert_cmpint (data.num_unregistered_subtree_calls, ==, 2);
nodes = get_nodes_at (c, "/foo/boss/executives"); nodes = get_nodes_at (c, "/foo/boss/executives");
g_assert (nodes != NULL); 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_bar_reg_id));
g_assert (g_dbus_connection_unregister_object (c, non_subtree_object_path_foo_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); 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 /* check that we no longer export any objects - TODO: it looks like there's a bug in