summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Ohly <patrick.ohly@intel.com>2009-12-04 12:47:47 +0100
committerPatrick Ohly <patrick.ohly@intel.com>2009-12-04 12:47:47 +0100
commit950fa6857e24854f41393357ee7afbb7e42184fa (patch)
tree7c1daa70a7d12234c2e09ec05364644304938f06
parentea8229923bfc181c641e29564b344d8c88aac747 (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.h2
-rw-r--r--src/gdbus/mainloop.c20
-rw-r--r--src/gdbus/test/example.cpp2
-rw-r--r--src/syncevo-dbus-server.cpp1
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()");