Re: [PATCH BlueZ] gdbus: Fix calling GetManagedObjects twice in a row

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Lucas,

On Mon, Apr 29, 2013 at 7:39 PM, Lucas De Marchi
<lucas.demarchi@xxxxxxxxxxxxxx> wrote:
> On Mon, Apr 29, 2013 at 11:45 AM, Luiz Augusto von Dentz
> <luiz.dentz@xxxxxxxxx> wrote:
>> Hi,
>>
>> On Thu, Apr 18, 2013 at 11:47 PM, Luiz Augusto von Dentz
>> <luiz.dentz@xxxxxxxxx> wrote:
>>> From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>
>>>
>>> Calling g_dbus_client_new followed by g_dbus_client_set_proxy_handlers
>>> cause two calls to GetManagedObjects in a row as GetNameOwner reply is
>>> asyncronously it triggers the second call because the handlers have
>>> been set by g_dbus_client_set_proxy_handlers.
>>> ---
>>>  gdbus/client.c | 25 ++++++++++++++++++-------
>>>  1 file changed, 18 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/gdbus/client.c b/gdbus/client.c
>>> index c2d2346..55f1d89 100644
>>> --- a/gdbus/client.c
>>> +++ b/gdbus/client.c
>>> @@ -40,6 +40,7 @@ struct GDBusClient {
>>>         char *base_path;
>>>         GPtrArray *match_rules;
>>>         DBusPendingCall *pending_call;
>>> +       DBusPendingCall *get_objects_call;
>>>         GDBusWatchFunction connect_func;
>>>         void *connect_data;
>>>         GDBusWatchFunction disconn_func;
>>> @@ -992,6 +993,8 @@ static void get_managed_objects_reply(DBusPendingCall *call, void *user_data)
>>>         DBusMessage *reply = dbus_pending_call_steal_reply(call);
>>>         DBusError error;
>>>
>>> +       g_dbus_client_ref(client);
>>> +
>>>         dbus_error_init(&error);
>>>
>>>         if (dbus_set_error_from_message(&error, reply) == TRUE) {
>>> @@ -1004,19 +1007,24 @@ static void get_managed_objects_reply(DBusPendingCall *call, void *user_data)
>>>  done:
>>>         dbus_message_unref(reply);
>>>
>>> +       dbus_pending_call_unref(client->get_objects_call);
>>> +       client->get_objects_call = NULL;
>>> +
>>>         g_dbus_client_unref(client);
>>>  }
>>>
>>>  static void get_managed_objects(GDBusClient *client)
>>>  {
>>>         DBusMessage *msg;
>>> -       DBusPendingCall *call;
>>>
>>>         if (!client->proxy_added && !client->proxy_removed) {
>>>                 refresh_properties(client);
>>>                 return;
>>>         }
>>>
>>> +       if (client->get_objects_call != NULL)
>>> +               return;
>>> +
>>>         msg = dbus_message_new_method_call(client->service_name, "/",
>>>                                         DBUS_INTERFACE_DBUS ".ObjectManager",
>>>                                                         "GetManagedObjects");
>>> @@ -1026,16 +1034,14 @@ static void get_managed_objects(GDBusClient *client)
>>>         dbus_message_append_args(msg, DBUS_TYPE_INVALID);
>>>
>>>         if (dbus_connection_send_with_reply(client->dbus_conn, msg,
>>> -                                                       &call, -1) == FALSE) {
>>> +                               &client->get_objects_call, -1) == FALSE) {
>>>                 dbus_message_unref(msg);
>>>                 return;
>>>         }
>>>
>>> -       g_dbus_client_ref(client);
>>> -
>>> -       dbus_pending_call_set_notify(call, get_managed_objects_reply,
>>> -                                                       client, NULL);
>>> -       dbus_pending_call_unref(call);
>>> +       dbus_pending_call_set_notify(client->get_objects_call,
>>> +                                               get_managed_objects_reply,
>>> +                                               client, NULL);
>
> Why don't you let the unref here, so you don't need to do it in
> g_dbus_client_unref() and get_managed_objects_reply(). This way the
> only ref is owned by libdbus which will free it when it's done.

But that means we have no control over any reference and from libdbus
perspective it can free whenever it likes which I think could break in
case where the callback is not called so I find it safer not to abuse
it here. Note that in get_name_owner we do the same, although some
other parts of the code it seems to not get this right and would
probably break in case the user data is freed before the pending call
completes.

--
Luiz Augusto von Dentz
--
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




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux