From 3618208598e69425544b513a13a219366051351b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 4 Apr 2009 04:53:24 +0200 Subject: [PATCH] Fix handling of watch functions --- gdbus/watch.c | 56 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/gdbus/watch.c b/gdbus/watch.c index 38bf3d7..7d7853f 100644 --- a/gdbus/watch.c +++ b/gdbus/watch.c @@ -37,6 +37,9 @@ #define error(fmt...) #define debug(fmt...) +static DBusHandlerResult name_exit_filter(DBusConnection *connection, + DBusMessage *message, void *user_data); + static guint listener_id = 0; static GSList *name_listeners = NULL; @@ -62,13 +65,11 @@ static struct name_data *name_data_find(DBusConnection *connection, current != NULL; current = current->next) { struct name_data *data = current->data; - if (name == NULL && data->name == NULL) { - if (connection == data->connection) - return data; - } else { - if (strcmp(name, data->name) == 0) - return data; - } + if (connection != data->connection) + continue; + + if (name == NULL || g_str_equal(name, data->name)) + return data; } return NULL; @@ -165,10 +166,18 @@ static void name_data_remove(DBusConnection *connection, g_free(cb); } - if (!data->callbacks) { - name_listeners = g_slist_remove(name_listeners, data); - name_data_free(data); - } + if (data->callbacks) + return; + + name_listeners = g_slist_remove(name_listeners, data); + name_data_free(data); + + /* Remove filter if there are no listeners left for the connection */ + data = name_data_find(connection, NULL); + if (!data) + dbus_connection_remove_filter(connection, + name_exit_filter, + NULL); } static gboolean add_match(DBusConnection *connection, const char *name) @@ -263,6 +272,12 @@ static DBusHandlerResult name_exit_filter(DBusConnection *connection, name_listeners = g_slist_remove(name_listeners, data); name_data_free(data); + /* Remove filter if there no listener left for the connection */ + data = name_data_find(connection, NULL); + if (!data) + dbus_connection_remove_filter(connection, name_exit_filter, + NULL); + remove_match(connection, name); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -275,7 +290,7 @@ guint g_dbus_add_service_watch(DBusConnection *connection, const char *name, { int first; - if (!listener_id) { + if (!name_data_find(connection, NULL)) { if (!dbus_connection_add_filter(connection, name_exit_filter, NULL, NULL)) { error("dbus_connection_add_filter() failed"); @@ -354,6 +369,12 @@ remove: name_listeners = g_slist_remove(name_listeners, data); name_data_free(data); + /* Remove filter if there are no listeners left for the connection */ + data = name_data_find(connection, NULL); + if (!data) + dbus_connection_remove_filter(connection, name_exit_filter, + NULL); + return TRUE; } @@ -361,13 +382,10 @@ void g_dbus_remove_all_watches(DBusConnection *connection) { struct name_data *data; - data = name_data_find(connection, NULL); - if (!data) { - error("name_listener_indicate_disconnect: no listener found"); - return; + while ((data = name_data_find(connection, NULL))) { + name_listeners = g_slist_remove(name_listeners, data); + name_data_call_and_free(data); } - debug("name_listener_indicate_disconnect"); - - name_data_call_and_free(data); + dbus_connection_remove_filter(connection, name_exit_filter, NULL); } -- 1.7.9.5