diff --git a/dbus/dbus-gmain.c b/dbus/dbus-gmain.c index 7496c65..300c5a2 100644 --- a/dbus/dbus-gmain.c +++ b/dbus/dbus-gmain.c @@ -238,6 +238,9 @@ io_handler_dispatch (GIOChannel *source, return TRUE; } +/* Attach the connection setup to the given watch, removing any + * previously-attached connection setup. + */ static void connection_setup_add_watch (ConnectionSetup *cs, DBusWatch *watch) @@ -250,8 +253,6 @@ connection_setup_add_watch (ConnectionSetup *cs, if (!dbus_watch_get_enabled (watch)) return; - g_assert (dbus_watch_get_data (watch) == NULL); - flags = dbus_watch_get_flags (watch); condition = G_IO_ERR | G_IO_HUP; @@ -285,7 +286,7 @@ connection_setup_remove_watch (ConnectionSetup *cs, handler = dbus_watch_get_data (watch); - if (handler == NULL) + if (handler == NULL || handler->cs != cs) return; io_handler_destroy_source (handler); diff --git a/test/core/30574.c b/test/core/30574.c new file mode 100644 index 0000000..51eaf30 --- /dev/null +++ b/test/core/30574.c @@ -0,0 +1,94 @@ +#include +#include +#include "dbus/dbus.h" +#include "glib.h" + +DBusConnection *bus; +GMainContext *main_context; + +typedef struct _SpiReentrantCallClosure +{ + GMainLoop *loop; + DBusMessage *reply; +} SpiReentrantCallClosure; + +static void +set_reply (DBusPendingCall * pending, void *user_data) +{ + SpiReentrantCallClosure* closure = (SpiReentrantCallClosure *) user_data; + + closure->reply = dbus_pending_call_steal_reply (pending); + dbus_connection_setup_with_g_main (bus, NULL); + + g_main_loop_quit (closure->loop); +} + +static DBusMessage * +send_and_allow_reentry (DBusConnection * bus, DBusMessage * message) +{ + DBusPendingCall *pending; + SpiReentrantCallClosure closure; + + closure.loop = g_main_loop_new (main_context, FALSE); + dbus_connection_setup_with_g_main (bus, main_context); + + if (!dbus_connection_send_with_reply (bus, message, &pending, 3000)) + { + dbus_connection_setup_with_g_main (bus, NULL); + return NULL; + } + dbus_pending_call_set_notify (pending, set_reply, (void *) &closure, NULL); + g_main_loop_run (closure.loop); + + g_main_loop_unref (closure.loop); + return closure.reply; +} + +main(int argc, const char *argv[]) +{ + DBusError error; + DBusMessage *message = NULL, *reply = NULL; + dbus_int32_t pid; + const char *str; + + 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); + if (!reply) + { + fprintf(stderr, "Sorry; dbus wouldn't answer me: %s\n", error.message); + exit(1); + } + 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; + } + if (!dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID)) + { + fprintf(stderr, "Sorry; can't communicate: %s\n", error.message); + exit(1); + } + exit (0); +} diff --git a/test/core/Makefile.am b/test/core/Makefile.am index 404a490..ccb17f6 100644 --- a/test/core/Makefile.am +++ b/test/core/Makefile.am @@ -54,6 +54,7 @@ noinst_PROGRAMS = \ peer-client \ test-types \ test-5688 \ + test-30574 \ test-unregister \ test-variant-recursion \ test-gvariant @@ -66,6 +67,9 @@ test_5688_SOURCES = \ my-object-marshal.c \ 5688.c +test_30574_SOURCES = \ + 30574.c + test_unregister_SOURCES = \ my-object.c \ my-object.h \ diff --git a/test/core/run-test.sh b/test/core/run-test.sh index 5d32d95..0351472 100755 --- a/test/core/run-test.sh +++ b/test/core/run-test.sh @@ -49,4 +49,5 @@ else ${DBUS_TOP_BUILDDIR}/libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/core/test-dbus-glib || die "test-dbus-glib failed" ${DBUS_TOP_BUILDDIR}/libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/core/test-variant-recursion || die "test-variant-recursion failed" ${DBUS_TOP_BUILDDIR}/libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/core/test-gvariant || die "test-gvariant failed" + ${DBUS_TOP_BUILDDIR}/libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/core/test-30574 || die "test-30574 failed" fi