Fix regression when removing watches
authorLuiz Augusto Von Dentz <luiz.dentz-von@nokia.com>
Fri, 8 Jan 2010 10:17:19 +0000 (12:17 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Fri, 8 Jan 2010 12:23:56 +0000 (04:23 -0800)
filter_data_find return the first data registered in this case so there is
no guarantee that it return the same data as passed to
filter_data_remove_callback which is the one that should be removed.

The fix is to simple cache the connection removing the correct data before
checking if there is any filter left.

gdbus/watch.c

index 42e158f..75e4210 100644 (file)
@@ -299,6 +299,8 @@ static struct filter_callback *filter_data_add_callback(
 static gboolean filter_data_remove_callback(struct filter_data *data,
                                                struct filter_callback *cb)
 {
+       DBusConnection *connection;
+
        data->callbacks = g_slist_remove(data->callbacks, cb);
        data->processed = g_slist_remove(data->processed, cb);
 
@@ -315,15 +317,17 @@ static gboolean filter_data_remove_callback(struct filter_data *data,
        if (data->registered && !remove_match(data))
                return FALSE;
 
+       connection = dbus_connection_ref(data->connection);
+       listeners = g_slist_remove(listeners, data);
+       filter_data_free(data);
+
        /* Remove filter if there are no listeners left for the connection */
-       data = filter_data_find(data->connection, NULL, NULL, NULL, NULL,
-                                       NULL);
+       data = filter_data_find(connection, NULL, NULL, NULL, NULL, NULL);
        if (!data)
-               dbus_connection_remove_filter(data->connection, message_filter,
+               dbus_connection_remove_filter(connection, message_filter,
                                                NULL);
 
-       listeners = g_slist_remove(listeners, data);
-       filter_data_free(data);
+       dbus_connection_unref(connection);
 
        return TRUE;
 }