summaryrefslogtreecommitdiffstats
path: root/gdbus/watch.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-08-06 22:10:19 -0700
committerMarcel Holtmann <marcel@holtmann.org>2009-08-06 22:13:09 -0700
commit2520e2682078d801d13dfac8a1ef467649e71cc3 (patch)
tree1ff490e0aaa7c357f3d66af8d4599ddb48eeaaa5 /gdbus/watch.c
parent572a89cce2afbb46ca751b236757923dd14e411a (diff)
downloadofono-2520e2682078d801d13dfac8a1ef467649e71cc3.tar.bz2
Fix blocking service watch initial connect handling
Diffstat (limited to 'gdbus/watch.c')
-rw-r--r--gdbus/watch.c97
1 files changed, 96 insertions, 1 deletions
diff --git a/gdbus/watch.c b/gdbus/watch.c
index c7a4e691..1de21da4 100644
--- a/gdbus/watch.c
+++ b/gdbus/watch.c
@@ -307,6 +307,97 @@ static DBusHandlerResult name_exit_filter(DBusConnection *connection,
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
+struct service_data {
+ DBusConnection *conn;
+ const char *name;
+ GDBusWatchFunction conn_func;
+ void *user_data;
+};
+
+static void service_reply(DBusPendingCall *call, void *user_data)
+{
+ struct service_data *data = user_data;
+ DBusMessage *reply;
+ DBusError error;
+ char **names;
+ int i, count;
+
+ reply = dbus_pending_call_steal_reply(call);
+ if (reply == NULL)
+ return;
+
+ dbus_error_init(&error);
+
+ if (dbus_message_get_args(reply, &error,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &names, &count,
+ DBUS_TYPE_INVALID) == FALSE) {
+ if (dbus_error_is_set(&error) == TRUE) {
+ error("%s", error.message);
+ dbus_error_free(&error);
+ } else {
+ error("Wrong arguments for name list");
+ }
+ goto done;
+ }
+
+ for (i = 0; i < count; i++)
+ if (g_strcmp0(names[i], data->name) == 0) {
+ if (data->conn_func)
+ data->conn_func(data->conn, data->user_data);
+ break;
+ }
+
+ g_strfreev(names);
+
+done:
+ dbus_message_unref(reply);
+}
+
+static void check_service(DBusConnection *connection, const char *name,
+ GDBusWatchFunction connect, void *user_data)
+{
+ DBusMessage *message;
+ DBusPendingCall *call;
+ struct service_data *data;
+
+ data = g_try_malloc0(sizeof(*data));
+ if (data == NULL) {
+ error("Can't allocate data structure");
+ return;
+ }
+
+ data->conn = connection;
+ data->name = name;
+ data->conn_func = connect;
+ data->user_data = user_data;
+
+ message = dbus_message_new_method_call(DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "ListNames");
+ if (message == NULL) {
+ error("Can't allocate new message");
+ g_free(data);
+ return;
+ }
+
+ if (dbus_connection_send_with_reply(connection, message,
+ &call, -1) == FALSE) {
+ error("Failed to execute method call");
+ g_free(data);
+ goto done;
+ }
+
+ if (call == NULL) {
+ error("D-Bus connection not available");
+ g_free(data);
+ goto done;
+ }
+
+ dbus_pending_call_set_notify(call, service_reply, data, NULL);
+
+done:
+ dbus_message_unref(message);
+}
+
guint g_dbus_add_service_watch(DBusConnection *connection, const char *name,
GDBusWatchFunction connect,
GDBusWatchFunction disconnect,
@@ -328,7 +419,7 @@ guint g_dbus_add_service_watch(DBusConnection *connection, const char *name,
/* The filter is already added if this is not the first callback
* registration for the name */
if (!first)
- return listener_id;
+ goto done;
if (name) {
debug("name_listener_add(%s)", name);
@@ -339,6 +430,10 @@ guint g_dbus_add_service_watch(DBusConnection *connection, const char *name,
}
}
+done:
+ if (connect)
+ check_service(connection, name, connect, user_data);
+
return listener_id;
}