<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jun 23, 2017 at 1:40 PM, Aleksander Morgado <span dir="ltr"><<a href="mailto:aleksander@aleksander.es" target="_blank">aleksander@aleksander.es</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hey Ben,<br>
<br>
See comments below.<br>
<div><div class="h5"><br>
On 23/06/17 18:11, Ben Chan wrote:<br>
> ---<br>
>  libmm-glib/mm-modem.c | 80 ++++++++++++++++++++++++------<wbr>---------------------<br>
>  1 file changed, 37 insertions(+), 43 deletions(-)<br>
><br>
> diff --git a/libmm-glib/mm-modem.c b/libmm-glib/mm-modem.c<br>
> index 7359357a..b725ec44 100644<br>
> --- a/libmm-glib/mm-modem.c<br>
> +++ b/libmm-glib/mm-modem.c<br>
> @@ -1752,9 +1752,6 @@ mm_modem_disable_sync (MMModem *self,<br>
>  /*****************************<wbr>******************************<wbr>******************/<br>
><br>
>  typedef struct {<br>
> -    MMModem *self;<br>
> -    GSimpleAsyncResult *result;<br>
> -    GCancellable *cancellable;<br>
>      gchar **bearer_paths;<br>
>      GList *bearer_objects;<br>
>      guint i;<br>
> @@ -1767,16 +1764,10 @@ bearer_object_list_free (GList *list)<br>
>  }<br>
><br>
>  static void<br>
> -list_bearers_context_<wbr>complete_and_free (ListBearersContext *ctx)<br>
> +list_bearers_context_free (ListBearersContext *ctx)<br>
>  {<br>
> -    g_simple_async_result_<wbr>complete_in_idle (ctx->result);<br>
> -<br>
>      g_strfreev (ctx->bearer_paths);<br>
>      bearer_object_list_free (ctx->bearer_objects);<br>
> -    g_object_unref (ctx->result);<br>
> -    if (ctx->cancellable)<br>
> -        g_object_unref (ctx->cancellable);<br>
> -    g_object_unref (ctx->self);<br>
>      g_slice_free (ListBearersContext, ctx);<br>
>  }<br>
><br>
> @@ -1795,69 +1786,75 @@ mm_modem_list_bearers_finish (MMModem *self,<br>
>                                GAsyncResult *res,<br>
>                                GError **error)<br>
>  {<br>
> -    GList *list;<br>
> -<br>
>      g_return_val_if_fail (MM_IS_MODEM (self), NULL);<br>
><br>
> -    if (g_simple_async_result_<wbr>propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))<br>
> -        return NULL;<br>
> -<br>
> -    list = g_simple_async_result_get_op_<wbr>res_gpointer (G_SIMPLE_ASYNC_RESULT (res));<br>
> -<br>
> -    /* The list we got, including the objects within, is owned by the async result;<br>
> -     * so we'll make sure we return a new list */<br>
> -    return g_list_copy_deep (list, (GCopyFunc)g_object_ref, NULL);<br>
> +    return g_task_propagate_pointer (G_TASK (res), error);<br>
>  }<br>
><br>
> -static void create_next_bearer (ListBearersContext *ctx);<br>
> +static void create_next_bearer (GTask *task);<br>
><br>
>  static void<br>
>  modem_list_bearers_build_<wbr>object_ready (GDBusConnection *connection,<br>
>                                         GAsyncResult *res,<br>
> -                                       ListBearersContext *ctx)<br>
> +                                       GTask *task)<br>
>  {<br>
>      GObject *bearer;<br>
>      GError *error = NULL;<br>
>      GObject *source_object;<br>
> +    ListBearersContext *ctx;<br>
><br>
>      source_object = g_async_result_get_source_<wbr>object (res);<br>
>      bearer = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), res, &error);<br>
>      g_object_unref (source_object);<br>
><br>
>      if (error) {<br>
> -        g_simple_async_result_take_<wbr>error (ctx->result, error);<br>
> -        list_bearers_context_complete_<wbr>and_free (ctx);<br>
> +        g_task_return_error (task, error);<br>
> +        g_object_unref (task);<br>
>          return;<br>
>      }<br>
><br>
> +    ctx = g_task_get_task_data (task);<br>
> +<br>
>      /* Keep the object */<br>
>      ctx->bearer_objects = g_list_prepend (ctx->bearer_objects, bearer);<br>
><br>
>      /* If no more bearers, just end here. */<br>
>      if (!ctx->bearer_paths[++ctx->i]) {<br>
> -        g_simple_async_result_set_op_<wbr>res_gpointer (ctx->result,<br>
> -                                                   ctx->bearer_objects,<br>
> -                                                   (GDestroyNotify)bearer_object_<wbr>list_free);<br>
> +        GList *bearer_objects;<br>
> +<br>
> +        bearer_objects = g_list_copy_deep (ctx->bearer_objects,<br>
> +                                           (GCopyFunc)g_object_ref,<br>
> +                                           NULL);<br>
>          ctx->bearer_objects = NULL;<br>
<br>
</div></div>I believe you also want to remove the previous line.<br>
<br>
You're building a whole new list of bearer_objects to return, that's ok, but that means you have to leave the original list untouched so that it is disposed in list_bearers_context_free(). Right now the list is leaking as the pointer to the head of the list was NULL-ed.<br>
<div><div class="h5"><br></div></div></blockquote><div><br></div><div>That's right, fixed in the v2. Later when we bump the glib dependency to 2.44+, we could do `bearer_objects = g_steal_pointer (ctx->bearer_objects)` instead.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
> -        list_bearers_context_complete_<wbr>and_free (ctx);<br>
> +<br>
> +        g_task_return_pointer (task,<br>
> +                               bearer_objects,<br>
> +                               (GDestroyNotify)bearer_object_<wbr>list_free);<br>
> +        g_object_unref (task);<br>
>          return;<br>
>      }<br>
><br>
>      /* Keep on creating next object */<br>
> -    create_next_bearer (ctx);<br>
> +    create_next_bearer (task);<br>
>  }<br>
><br>
>  static void<br>
> -create_next_bearer (ListBearersContext *ctx)<br>
> +create_next_bearer (GTask *task)<br>
>  {<br>
> +    MMModem *self;<br>
> +    ListBearersContext *ctx;<br>
> +<br>
> +    self = g_task_get_source_object (task);<br>
> +    ctx = g_task_get_task_data (task);<br>
> +<br>
>      g_async_initable_new_async (MM_TYPE_BEARER,<br>
>                                  G_PRIORITY_DEFAULT,<br>
> -                                ctx->cancellable,<br>
> +                                g_task_get_cancellable (task),<br>
>                                  (GAsyncReadyCallback)modem_<wbr>list_bearers_build_object_<wbr>ready,<br>
> -                                ctx,<br>
> +                                task,<br>
>                                  "g-flags",          G_DBUS_PROXY_FLAGS_DO_NOT_<wbr>AUTO_START,<br>
>                                  "g-name",           MM_DBUS_SERVICE,<br>
> -                                "g-connection",     g_dbus_proxy_get_connection (G_DBUS_PROXY (ctx->self)),<br>
> +                                "g-connection",     g_dbus_proxy_get_connection (G_DBUS_PROXY (self)),<br>
>                                  "g-object-path",    ctx->bearer_paths[ctx->i],<br>
>                                  "g-interface-name", "org.freedesktop.<wbr>ModemManager1.Bearer",<br>
>                                  NULL);<br>
> @@ -1884,31 +1881,28 @@ mm_modem_list_bearers (MMModem *self,<br>
>                         gpointer user_data)<br>
>  {<br>
>      ListBearersContext *ctx;<br>
> +    GTask *task;<br>
><br>
>      g_return_if_fail (MM_IS_MODEM (self));<br>
><br>
>      ctx = g_slice_new0 (ListBearersContext);<br>
> -    ctx->self = g_object_ref (self);<br>
> -    ctx->result = g_simple_async_result_new (G_OBJECT (self),<br>
> -                                             callback,<br>
> -                                             user_data,<br>
> -                                             mm_modem_list_bearers);<br>
> -    if (cancellable)<br>
> -        ctx->cancellable = g_object_ref (cancellable);<br>
><br>
>      /* Read from the property, skip List() */<br>
>      ctx->bearer_paths = mm_gdbus_modem_dup_bearers (MM_GDBUS_MODEM (self));<br>
><br>
> +    task = g_task_new (self, cancellable, callback, user_data);<br>
> +    g_task_set_task_data (task, ctx, (GDestroyNotify)list_bearers_<wbr>context_free);<br>
> +<br>
>      /* If no bearers, just end here. */<br>
>      if (!ctx->bearer_paths || !ctx->bearer_paths[0]) {<br>
> -        g_simple_async_result_set_op_<wbr>res_gpointer (ctx->result, NULL, NULL);<br>
> -        list_bearers_context_complete_<wbr>and_free (ctx);<br>
> +        g_task_return_pointer (task, NULL, NULL);<br>
> +        g_object_unref (task);<br>
>          return;<br>
>      }<br>
><br>
>      /* Got list of paths. If at least one found, start creating objects for each */<br>
>      ctx->i = 0;<br>
> -    create_next_bearer (ctx);<br>
> +    create_next_bearer (task);<br>
>  }<br>
><br>
>  /**<br>
><br>
<br>
<br>
--<br>
</div></div>Aleksander<br>
<a href="https://aleksander.es" rel="noreferrer" target="_blank">https://aleksander.es</a><br>
</blockquote></div><br></div></div>