From c5bf213132daa88f681a9df99af2f49b8415a620 Mon Sep 17 00:00:00 2001 From: Mike Gorse Date: Fri, 31 Aug 2012 13:24:19 -0500 Subject: [PATCH] Remove erroneous assert from connection_setup_add_timeout When switching a connection from one main loop to another, timeouts are moved to the new connection, so connection_setup_add_timeout gets called on the new connection for all timeouts that were set on the old connection. This means that the timeout's data can, in fact, be non-NULL, and it will be freed / removed from the old connection as a side-effect of adding it to the new connection. A similar assert was removed from dbus_connection_add_watch a while ago as part of the original patch for this bug. Also, clean up the regression test a bit, and test that a DBusConnection can be migrated when a pending call is present. https://bugs.freedesktop.org/show_bug.cgi?id=30574 --- dbus/dbus-gmain.c | 2 -- test/core/30574.c | 69 +++++++++++++++++++++++++++++++---------------------- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/dbus/dbus-gmain.c b/dbus/dbus-gmain.c index e6ce52b..cd34c1d 100644 --- a/dbus/dbus-gmain.c +++ b/dbus/dbus-gmain.c @@ -344,8 +344,6 @@ connection_setup_add_timeout (ConnectionSetup *cs, if (!dbus_timeout_get_enabled (timeout)) return; - g_assert (dbus_timeout_get_data (timeout) == NULL); - handler = g_new0 (TimeoutHandler, 1); handler->cs = cs; handler->timeout = timeout; diff --git a/test/core/30574.c b/test/core/30574.c index 3cbe1b5..6364604 100644 --- a/test/core/30574.c +++ b/test/core/30574.c @@ -27,13 +27,15 @@ set_reply (DBusPendingCall * pending, void *user_data) } static DBusMessage * -send_and_allow_reentry (DBusConnection * bus, DBusMessage * message) +send_and_allow_reentry (DBusConnection * bus, DBusMessage * message, + dbus_bool_t switch_after_send) { DBusPendingCall *pending; SpiReentrantCallClosure closure; closure.loop = g_main_loop_new (main_context, FALSE); - dbus_connection_setup_with_g_main (bus, main_context); + dbus_connection_setup_with_g_main (bus, (switch_after_send ? NULL : + main_context)); if (!dbus_connection_send_with_reply (bus, message, &pending, 3000)) { @@ -41,49 +43,35 @@ send_and_allow_reentry (DBusConnection * bus, DBusMessage * message) return NULL; } dbus_pending_call_set_notify (pending, set_reply, (void *) &closure, NULL); + if (switch_after_send) + dbus_connection_setup_with_g_main (bus, main_context); g_main_loop_run (closure.loop); g_main_loop_unref (closure.loop); + dbus_pending_call_unref (pending); return closure.reply; } -int -main(int argc, const char *argv[]) +static void +send_test_message (dbus_bool_t switch_after_send) { - DBusError error; - DBusMessage *message = NULL, *reply = NULL; + DBusMessage *message, *reply; const char *str; + DBusError error; - main_context = g_main_context_new (); dbus_error_init (&error); - bus = dbus_bus_get (DBUS_BUS_SESSION, &error); - if (!bus) - { - fprintf(stderr, "Couldn't connect to bus: %s\n", error.name); - return 1; - } - dbus_connection_setup_with_g_main (bus, NULL); - message = dbus_message_new_method_call ("org.freedesktop.DBus", "/org/freedesktop/DBus", DBUS_INTERFACE_DBUS, "GetId"); - reply = send_and_allow_reentry (bus, message); - if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) - { - char *err; - dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &err, DBUS_TYPE_INVALID); - fprintf (stderr, "Got error: %s\n", err); - return 1; - } - dbus_message_unref (reply); - dbus_message_unref (message); - message = dbus_message_new_method_call ("org.freedesktop.DBus", "/org/freedesktop/DBus", DBUS_INTERFACE_DBUS, "GetId"); - reply = send_and_allow_reentry (bus, message); + message = dbus_message_new_method_call ("org.freedesktop.DBus", + "/org/freedesktop/DBus", + DBUS_INTERFACE_DBUS, "GetId"); + reply = send_and_allow_reentry (bus, message, switch_after_send); if (!reply) { - fprintf(stderr, "Sorry; dbus wouldn't answer me: %s\n", error.message); + fprintf(stderr, "Got no reply from send_and_allow_reentry\n"); exit(1); } if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) { - char *err; + char *err = NULL; dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &err, DBUS_TYPE_INVALID); fprintf (stderr, "Got error: %s\n", err); return 1; @@ -93,6 +81,29 @@ main(int argc, const char *argv[]) fprintf(stderr, "Sorry; can't communicate: %s\n", error.message); exit(1); } + dbus_message_unref (reply); + dbus_message_unref (message); +} + +int +main(int argc, const char *argv[]) +{ + DBusError error; + DBusMessage *message = NULL, *reply = NULL; + + main_context = g_main_context_new (); + dbus_error_init (&error); + bus = dbus_bus_get (DBUS_BUS_SESSION, &error); + if (!bus) + { + fprintf(stderr, "Couldn't connect to bus: %s\n", error.name); + return 1; + } + dbus_connection_setup_with_g_main (bus, NULL); + send_test_message (FALSE); + send_test_message (FALSE); + send_test_message (TRUE); + return 0; } -- 1.7.10.4