From: Marcel Holtmann Date: Fri, 7 Aug 2009 05:10:19 +0000 (-0700) Subject: Fix blocking service watch initial connect handling X-Git-Tag: 0.39~67 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3454ea05090dc6b796396be43e2470c112b97d11;p=platform%2Fupstream%2Fconnman.git Fix blocking service watch initial connect handling --- diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h index fa618a5..244f797 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 eaba42e..a06ed22 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 c7a4e69..1de21da 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; }