Re: [PATCH BlueZ] gdbus: Fix removal of filter after last filter_data |
|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
On Mon, Jun 25, 2012 at 5:51 AM, Luiz Augusto von Dentz
<luiz.dentz@xxxxxxxxx> wrote:
> Hi Lucas,
>
> On Sat, Jun 23, 2012 at 5:02 PM, Lucas De Marchi
> <lucas.demarchi@xxxxxxxxxxxxxx> wrote:
>> If there's a signal watch that's also watching for name
>> (data->name_watch) currently we are trying to remove the message_filter
>> twice since we may have the following call chain:
>>
>> filter_data_remove_callback()
>> filter_data_free()
>> g_dbus_remove_watch()
>> filter_data_remove_callback()
>> filter_data_free()
>> dbus_connection_remove_filter()
>> dbus_connection_remove_filter()
>>
>> Because of this we can't currently watch for signals passing the bus
>> name. After this patch we don't have this issue anymore.
>>
>> We fix this by checking if we are the last filter_data before calling
>> filter_data_free and thus not calling dbus_connection_remove_filter()
>> twice.
>> ---
>> gdbus/watch.c | 12 +++++++++---
>> 1 file changed, 9 insertions(+), 3 deletions(-)
>>
>> diff --git a/gdbus/watch.c b/gdbus/watch.c
>> index 9a716b0..6fed264 100644
>> --- a/gdbus/watch.c
>> +++ b/gdbus/watch.c
>> @@ -350,6 +350,7 @@ static gboolean filter_data_remove_callback(struct filter_data *data,
>> struct filter_callback *cb)
>> {
>> DBusConnection *connection;
>> + struct filter_data *data_next;
>>
>> data->callbacks = g_slist_remove(data->callbacks, cb);
>> data->processed = g_slist_remove(data->processed, cb);
>> @@ -376,12 +377,17 @@ static gboolean filter_data_remove_callback(struct filter_data *data,
>>
>> connection = dbus_connection_ref(data->connection);
>> listeners = g_slist_remove(listeners, data);
>> +
>> + /*
>> + * filter_data_free() may remove the latest data - we need to check
>> + * before it runs if it's our duty to remove the filter
>> + */
>> + data_next = filter_data_find(connection, NULL, NULL, NULL, NULL, NULL,
>> + NULL);
>> filter_data_free(data);
>>
>> /* Remove filter if there are no listeners left for the connection */
>> - data = filter_data_find(connection, NULL, NULL, NULL, NULL, NULL,
>> - NULL);
>> - if (data == NULL)
>> + if (data_next == NULL)
>> dbus_connection_remove_filter(connection, message_filter,
>> NULL);
>>
>> --
>> 1.7.11
>
> Hmm do you have checks enabled in libdbus? It seems this is cause by:
>
> #ifndef DBUS_DISABLE_CHECKS
> if (filter == NULL)
> {
> _dbus_warn_check_failed ("Attempt to remove filter function %p
> user data %p, but no such filter has been added\n",
> function, user_data);
> return;
> }
> #endif
Probably... this is the stock libdbus from Archlinux. I also found
interest that all possible users of g_dbus_add_signal_watch() with a
bus name were passing a NULL, which is clearly wrong. That made me
think it was like this to workaround this bug.
>
> Anyway I couldn't reproduce by changing ofono with stock libdbus from
> FC 17, although I see the problem just by looking at the code, but
> there other places where this need to be checked as well and the code
> could be simplified:
>
> diff --git a/gdbus/watch.c b/gdbus/watch.c
> index 9a716b0..d749176 100644
> --- a/gdbus/watch.c
> +++ b/gdbus/watch.c
> @@ -376,15 +376,14 @@ static gboolean
> filter_data_remove_callback(struct filter_data *data,
>
> 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(connection, NULL, NULL, NULL, NULL, NULL,
> - NULL);
> - if (data == NULL)
> + if (filter_data_find(connection, NULL, NULL, NULL, NULL, NULL,
> + NULL) == NULL)
> dbus_connection_remove_filter(connection, message_filter,
> NULL);
>
> + filter_data_free(data);
> dbus_connection_unref(connection);
>
> return TRUE;
ahn... right. We already removed data from listeners list so we can
call dbus_connection_remove_filter() before filter_data_free().
Ack.
Lucas De Marchi
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
[Bluez Devel]
[Linux USB Devel]
[Linux Media Drivers]
[Linux Audio Users]
[Yosemite News]
[Yosemite Photos]
[Free Online Dating]
[Bluez Devel]
[Linux Kernel]
[Linux SCSI]
[XFree86]
[Big List of Linux Books]