<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>