diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2009-12-04 12:47:47 +0100 |
---|---|---|
committer | Patrick Ohly <patrick.ohly@intel.com> | 2009-12-04 12:47:47 +0100 |
commit | 950fa6857e24854f41393357ee7afbb7e42184fa (patch) | |
tree | 7c1daa70a7d12234c2e09ec05364644304938f06 | |
parent | ea8229923bfc181c641e29564b344d8c88aac747 (diff) |
gdbus: allow using private connectiondbus-sharing
This change was necessary because it turned out that using
g_dbus_setup_bus() and later dbus_g_bus_get() leads to problems
(assertion about watch data on Moblin 2.1, CRITICAL warning
and possibly other issues on Debian Lenny).
It seems that sharing a DBusConnection between different layers on top
of libdbus is either not supported or incorrectly implemented, at
least in glib-dbus.
The problem was found in SyncEvolution when using a libecal/ebook
which call D-Bus under the hood (Moblin Bugzilla #8460). SyncEvolution
has no control over those calls, therefore making the connection used
by the syncevo-dbus-server private was the easier alternative.
-rw-r--r-- | src/gdbus/gdbus.h | 2 | ||||
-rw-r--r-- | src/gdbus/mainloop.c | 20 | ||||
-rw-r--r-- | src/gdbus/test/example.cpp | 2 | ||||
-rw-r--r-- | src/syncevo-dbus-server.cpp | 1 |
4 files changed, 20 insertions, 5 deletions
diff --git a/src/gdbus/gdbus.h b/src/gdbus/gdbus.h index 8a7e3498..e10dcae9 100644 --- a/src/gdbus/gdbus.h +++ b/src/gdbus/gdbus.h @@ -208,10 +208,12 @@ typedef struct { } GDBusPropertyTable; void g_dbus_setup_connection(DBusConnection *connection, + gboolean unshared, GMainContext *context); void g_dbus_cleanup_connection(DBusConnection *connection); DBusConnection *g_dbus_setup_bus(DBusBusType type, const char *name, + gboolean unshared, DBusError *error); DBusConnection *g_dbus_setup_address(const char *address, DBusError *error); diff --git a/src/gdbus/mainloop.c b/src/gdbus/mainloop.c index fd7a71b4..1e5113ea 100644 --- a/src/gdbus/mainloop.c +++ b/src/gdbus/mainloop.c @@ -39,6 +39,7 @@ typedef struct { DBusConnection *connection; GMainContext *context; GSource *queue; + gboolean unshared; } ConnectionData; typedef struct { @@ -317,6 +318,7 @@ static void wakeup_context(void *user_data) } static ConnectionData *setup_connection(DBusConnection *connection, + gboolean unshared, GMainContext *context) { ConnectionData *data; @@ -326,6 +328,7 @@ static ConnectionData *setup_connection(DBusConnection *connection, data = g_new0(ConnectionData, 1); data->context = g_main_context_ref(context); + data->unshared = unshared; DBG("connection data %p", data); @@ -353,6 +356,8 @@ static void free_connection(void *memory) //g_dbus_unregister_all_objects(data->connection); + if (data->unshared) + dbus_connection_close(data->connection); dbus_connection_unref(data->connection); g_main_context_unref(data->context); @@ -363,6 +368,7 @@ static void free_connection(void *memory) /** * g_dbus_setup_connection: * @connection: a #DBusConnection + * @unshared: the connection is private and must be closed explicitly * @context: a #GMainContext or #NULL for default context * * Setup connection with main context @@ -373,6 +379,7 @@ static void free_connection(void *memory) * doing something specialized. */ void g_dbus_setup_connection(DBusConnection *connection, + gboolean unshared, GMainContext *context) { ConnectionData *data; @@ -393,7 +400,7 @@ void g_dbus_setup_connection(DBusConnection *connection, if (context == NULL) context = g_main_context_default(); - data = setup_connection(connection, context); + data = setup_connection(connection, unshared, context); if (data == NULL) return; @@ -438,6 +445,9 @@ void g_dbus_cleanup_connection(DBusConnection *connection) * g_dbus_setup_bus: * @type: a #DBusBusType * @name: well known name + * @unshared: use dbus_bus_get_private() to ensure that we have the connection + * for ourself (otherwise assertions and CRITICAL warnings were triggered + * inside glib-dbus when the app also used that) * @error: a #DBusError * * Connect to bus and setup connection @@ -449,13 +459,15 @@ void g_dbus_cleanup_connection(DBusConnection *connection) * Returns: newly setup #DBusConnection */ DBusConnection *g_dbus_setup_bus(DBusBusType type, const char *name, + gboolean unshared, DBusError *error) { DBusConnection *connection; DBG("type %d name %s error %p", type, name, error); - connection = dbus_bus_get(type, error); + connection = unshared ? dbus_bus_get_private(type, error) : + dbus_bus_get(type, error); if (error != NULL) { if (dbus_error_is_set(error) == TRUE) @@ -481,7 +493,7 @@ DBusConnection *g_dbus_setup_bus(DBusBusType type, const char *name, } } - g_dbus_setup_connection(connection, NULL); + g_dbus_setup_connection(connection, unshared, NULL); return connection; } @@ -515,7 +527,7 @@ DBusConnection *g_dbus_setup_address(const char *address, DBusError *error) if (connection == NULL) return NULL; - g_dbus_setup_connection(connection, NULL); + g_dbus_setup_connection(connection, FALSE, NULL); return connection; } diff --git a/src/gdbus/test/example.cpp b/src/gdbus/test/example.cpp index 3a5e099e..d0dfd7f8 100644 --- a/src/gdbus/test/example.cpp +++ b/src/gdbus/test/example.cpp @@ -255,7 +255,7 @@ int main(int argc, char *argv[]) dbus_error_init(&err); - conn = g_dbus_setup_bus(DBUS_BUS_SESSION, "org.example", &err); + conn = g_dbus_setup_bus(DBUS_BUS_SESSION, "org.example", false, &err); if (conn == NULL) { if (dbus_error_is_set(&err) == TRUE) { fprintf(stderr, "%s\n", err.message); diff --git a/src/syncevo-dbus-server.cpp b/src/syncevo-dbus-server.cpp index 839d064f..3f40df21 100644 --- a/src/syncevo-dbus-server.cpp +++ b/src/syncevo-dbus-server.cpp @@ -2984,6 +2984,7 @@ int main(int argc, char **argv) DBusErrorCXX err; DBusConnectionPtr conn = g_dbus_setup_bus(DBUS_BUS_SESSION, "org.syncevolution", + true, &err); if (!conn) { err.throwFailure("g_dbus_setup_bus()"); |