summaryrefslogtreecommitdiff
path: root/gdbus
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:10:19 -0700
commit3454ea05090dc6b796396be43e2470c112b97d11 (patch)
tree2c14943d1a4c0518065899a65fcd5d951988a437 /gdbus
parent96a0aa27fbca9d508e920576d809a1237d6d47a7 (diff)
downloadconnman-3454ea05090dc6b796396be43e2470c112b97d11.tar.gz
connman-3454ea05090dc6b796396be43e2470c112b97d11.tar.bz2
connman-3454ea05090dc6b796396be43e2470c112b97d11.zip
Fix blocking service watch initial connect handling
Diffstat (limited to 'gdbus')
-rw-r--r--gdbus/gdbus.h2
-rw-r--r--gdbus/mainloop.c43
-rw-r--r--gdbus/watch.c97
3 files changed, 96 insertions, 46 deletions
diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index fa618a52..244f7977 100644
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -43,8 +43,6 @@ DBusConnection *g_dbus_setup_bus(DBusBusType type, const char *name,
gboolean g_dbus_request_name(DBusConnection *connection, const char *name,
DBusError *error);
-gboolean g_dbus_check_service(DBusConnection *connection, const char *name);
-
gboolean g_dbus_set_disconnect_function(DBusConnection *connection,
GDBusWatchFunction function,
void *user_data, DBusFreeFunction destroy);
diff --git a/gdbus/mainloop.c b/gdbus/mainloop.c
index eaba42ea..a06ed220 100644
--- a/gdbus/mainloop.c
+++ b/gdbus/mainloop.c
@@ -281,49 +281,6 @@ gboolean g_dbus_request_name(DBusConnection *connection, const char *name,
return TRUE;
}
-gboolean g_dbus_check_service(DBusConnection *connection, const char *name)
-{
- DBusMessage *message, *reply;
- const char **names;
- int i, count;
- gboolean result = FALSE;
-
- 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");
- return FALSE;
- }
-
- reply = dbus_connection_send_with_reply_and_block(connection,
- message, -1, NULL);
-
- dbus_message_unref(message);
-
- if (reply == NULL) {
- error("Failed to execute method call");
- return FALSE;
- }
-
- if (dbus_message_get_args(reply, NULL,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
- &names, &count, DBUS_TYPE_INVALID) == FALSE) {
- error("Failed to read name list");
- goto done;
- }
-
- for (i = 0; i < count; i++)
- if (g_str_equal(names[i], name) == TRUE) {
- result = TRUE;
- break;
- }
-
-done:
- dbus_message_unref(reply);
-
- return result;
-}
-
gboolean g_dbus_set_disconnect_function(DBusConnection *connection,
GDBusWatchFunction function,
void *user_data, DBusFreeFunction destroy)
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;
}