<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Aug 20, 2017 at 2:10 AM, 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:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">---<br>
 src/libmbim-glib/mbim-device.c | 389 ++++++++++++++++++++++--------<wbr>-----------<br>
 1 file changed, 207 insertions(+), 182 deletions(-)<br>
<br>
diff --git a/src/libmbim-glib/mbim-<wbr>device.c b/src/libmbim-glib/mbim-<wbr>device.c<br>
index 4b7d431..082f081 100644<br>
--- a/src/libmbim-glib/mbim-<wbr>device.c<br>
+++ b/src/libmbim-glib/mbim-<wbr>device.c<br>
@@ -144,140 +144,155 @@ static void device_report_error (MbimDevice   *self,<br>
 /* Message transactions (private) */<br>
<br>
 typedef struct {<br>
-    MbimDevice *self;<br>
-    guint32 transaction_id;<br>
-    TransactionType type;<br>
+    MbimDevice      *self;<br>
+    guint32          transaction_id;<br>
+    TransactionType  type;<br>
 } TransactionWaitContext;<br>
<br>
 typedef struct {<br>
-    MbimDevice *self;<br>
-    MbimMessage *fragments;<br>
-    MbimMessageType type;<br>
-    guint32 transaction_id;<br>
-    GSimpleAsyncResult *result;<br>
-    GSource *timeout_source;<br>
-    GCancellable *cancellable;<br>
-    gulong cancellable_id;<br>
+    MbimMessage            *fragments;<br>
+    MbimMessageType         type;<br>
+    guint32                 transaction_id;<br>
+    GSource                *timeout_source;<br>
+    GCancellable           *cancellable;<br>
+    gulong                  cancellable_id;<br>
     TransactionWaitContext *wait_ctx;<br>
-} Transaction;<br>
+} TransactionContext;<br>
+<br>
+static void<br>
+transaction_context_free (TransactionContext *ctx)<br>
+{<br>
+    if (ctx->fragments)<br>
+        mbim_message_unref (ctx->fragments);<br>
+<br>
+    if (ctx->timeout_source)<br>
+        g_source_destroy (ctx->timeout_source);<br>
+<br>
+    if (ctx->cancellable) {<br></blockquote><div><br></div><div>[Ben] Looks like ctx->cancellable is never assigned.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+        if (ctx->cancellable_id)<br>
+            g_cancellable_disconnect (ctx->cancellable, ctx->cancellable_id);<br>
+        g_object_unref (ctx->cancellable);<br>
+    }<br>
+<br>
+    if (ctx->wait_ctx)<br>
+        g_slice_free (TransactionWaitContext, ctx->wait_ctx);<br>
+<br>
+    g_slice_free (TransactionContext, ctx);<br>
+}<br>
<br>
 /* #define TRACE_TRANSACTION 1 */<br>
 #ifdef TRACE_TRANSACTION<br>
 static void<br>
-trace_transaction (Transaction *tr,<br>
-                   const gchar *state)<br>
+transaction_task_trace (GTask       *task,<br>
+                        const gchar *state)<br>
 {<br>
+    MbimDevice         *self;<br>
+    TransactionContext *ctx;<br>
+<br>
+    self = g_task_get_source_object (task);<br>
+    ctx  = g_task_get_task_data     (task);<br>
+<br>
     g_debug ("[%s,%u] transaction %s: %s",<br>
-             tr->self->priv->path_display,<br>
-             tr->transaction_id,<br>
-             mbim_message_type_get_string (tr->type),<br>
+             self->priv->path_display,<br>
+             ctx->transaction_id,<br>
+             mbim_message_type_get_string (ctx->type),<br>
              state);<br>
 }<br>
 #else<br>
-# define trace_transaction(...)<br>
+# define transaction_task_trace(...)<br>
 #endif<br>
<br>
-static Transaction *<br>
-transaction_new (MbimDevice          *self,<br>
-                 MbimMessageType      type,<br>
-                 guint32              transaction_id,<br>
-                 GCancellable        *cancellable,<br>
-                 GAsyncReadyCallback  callback,<br>
-                 gpointer             user_data)<br>
+static GTask *<br>
+transaction_task_new (MbimDevice          *self,<br>
+                      MbimMessageType      type,<br>
+                      guint32              transaction_id,<br>
+                      GCancellable        *cancellable,<br>
+                      GAsyncReadyCallback  callback,<br>
+                      gpointer             user_data)<br>
 {<br>
-    Transaction *tr;<br>
+    GTask              *task;<br>
+    TransactionContext *ctx;<br>
<br>
-    tr = g_slice_new0 (Transaction);<br>
-    tr->type = type;<br>
-    tr->transaction_id = transaction_id;<br>
-    tr->self = g_object_ref (self);<br>
-    tr->result = g_simple_async_result_new (G_OBJECT (self),<br>
-                                            callback,<br>
-                                            user_data,<br>
-                                            transaction_new);<br>
-    if (cancellable)<br>
-        tr->cancellable = g_object_ref (cancellable);<br>
+    task = g_task_new (self, cancellable, callback, user_data);<br>
+<br>
+    ctx = g_slice_new0 (TransactionContext);<br>
+    ctx->type = type;<br>
+    ctx->transaction_id = transaction_id;<br>
+    g_task_set_task_data (task, ctx, (GDestroyNotify) transaction_context_free);<br>
<br>
-    trace_transaction (tr, "new");<br>
+    transaction_task_trace (task, "new");<br>
<br>
-    return tr;<br>
+    return task;<br>
 }<br>
<br>
 static void<br>
-transaction_complete_and_free (Transaction  *tr,<br>
-                               const GError *error)<br>
+transaction_task_complete_<wbr>and_free (GTask        *task,<br>
+                                    const GError *error)<br>
 {<br>
-    if (tr->timeout_source)<br>
-        g_source_destroy (tr->timeout_source);<br>
-<br>
-    if (tr->cancellable) {<br>
-        if (tr->cancellable_id)<br>
-            g_cancellable_disconnect (tr->cancellable, tr->cancellable_id);<br>
-        g_object_unref (tr->cancellable);<br>
-    }<br>
+    TransactionContext *ctx;<br>
<br>
-    if (tr->wait_ctx)<br>
-        g_slice_free (TransactionWaitContext, tr->wait_ctx);<br>
+    ctx = g_task_get_task_data (task);<br>
<br>
     if (error) {<br>
-        trace_transaction (tr, "complete: error");<br>
-        g_simple_async_result_set_<wbr>from_error (tr->result, error);<br>
-        if (tr->fragments)<br>
-            mbim_message_unref (tr->fragments);<br>
+        transaction_task_trace (task, "complete: error");<br>
+        g_task_return_error (task, g_error_copy (error));<br>
     } else {<br>
-        trace_transaction (tr, "complete: response");<br>
-        g_assert (tr->fragments != NULL);<br>
-        g_simple_async_result_set_op_<wbr>res_gpointer (tr->result,<br>
-                                                   tr->fragments,<br>
-                                                   (GDestroyNotify) mbim_message_unref);<br>
+        transaction_task_trace (task, "complete: response");<br>
+        g_assert (ctx->fragments != NULL);<br>
+        g_task_return_pointer (task, mbim_message_ref (ctx->fragments), (GDestroyNotify) mbim_message_unref);<br>
     }<br>
<br>
-    g_simple_async_result_<wbr>complete_in_idle (tr->result);<br>
-    g_object_unref (tr->result);<br>
-    g_object_unref (tr->self);<br>
-    g_slice_free (Transaction, tr);<br>
+    g_object_unref (task);<br>
 }<br>
<br>
-static Transaction *<br>
+static GTask *<br>
 device_release_transaction (MbimDevice      *self,<br>
                             TransactionType  type,<br>
                             MbimMessageType  expected_type,<br>
                             guint32          transaction_id)<br>
 {<br>
-    Transaction *tr = NULL;<br>
+    GTask              *task;<br>
+    TransactionContext *ctx;<br>
<br>
     /* Only return transaction if it was released from the HT */<br>
-    if (self->priv->transactions[<wbr>type]) {<br>
-        tr = g_hash_table_lookup (self->priv->transactions[<wbr>type], GUINT_TO_POINTER (transaction_id));<br>
-        if (tr && ((tr->type == expected_type) || (expected_type == MBIM_MESSAGE_TYPE_INVALID))) {<br>
-            /* If found, remove it from the HT */<br>
-            trace_transaction (tr, "release");<br>
-            g_hash_table_remove (self->priv->transactions[<wbr>type], GUINT_TO_POINTER (transaction_id));<br>
-            return tr;<br>
-        }<br>
+    if (!self->priv->transactions[<wbr>type])<br>
+        return NULL;<br>
+<br>
+    task = g_hash_table_lookup (self->priv->transactions[<wbr>type], GUINT_TO_POINTER (transaction_id));<br>
+    if (!task)<br>
+        return NULL;<br>
+<br>
+    ctx = g_task_get_task_data (task);<br>
+    if ((ctx->type == expected_type) || (expected_type == MBIM_MESSAGE_TYPE_INVALID)) {<br>
+        /* If found, remove it from the HT */<br>
+        transaction_task_trace (task, "release");<br>
+        g_hash_table_remove (self->priv->transactions[<wbr>type], GUINT_TO_POINTER (transaction_id));<br>
+        return task;<br>
     }<br>
<br>
     return NULL;<br>
 }<br>
<br>
 static gboolean<br>
-transaction_timed_out (TransactionWaitContext *ctx)<br>
+transaction_timed_out (TransactionWaitContext *wait_ctx)<br>
 {<br>
-    Transaction *tr;<br>
-    GError *error = NULL;<br>
+    GTask              *task;<br>
+    TransactionContext *ctx;<br>
+    GError             *error = NULL;<br>
<br>
-    tr = device_release_transaction (ctx->self,<br>
-                                     ctx->type,<br>
-                                     MBIM_MESSAGE_TYPE_INVALID,<br>
-                                     ctx->transaction_id);<br>
-    if (!tr)<br>
+    task = device_release_transaction (wait_ctx->self,<br>
+                                       wait_ctx->type,<br>
+                                       MBIM_MESSAGE_TYPE_INVALID,<br>
+                                       wait_ctx->transaction_id);<br>
+    if (!task)<br>
         /* transaction already completed */<br>
         return FALSE;<br>
<br>
-    tr->timeout_source = NULL;<br>
+    ctx = g_task_get_task_data (task);<br>
+    ctx->timeout_source = NULL;<br>
<br>
     /* If no fragment was received, complete transaction with a timeout error */<br>
-    if (!tr->fragments)<br>
+    if (!ctx->fragments)<br>
         error = g_error_new (MBIM_CORE_ERROR,<br>
                              MBIM_CORE_ERROR_TIMEOUT,<br>
                              "Transaction timed out");<br>
@@ -288,78 +303,87 @@ transaction_timed_out (TransactionWaitContext *ctx)<br>
                              "Fragment timed out");<br>
<br>
         /* Also notify to the modem */<br>
-        device_report_error (ctx->self,<br>
-                             tr->transaction_id,<br>
+        device_report_error (wait_ctx->self,<br>
+                             wait_ctx->transaction_id,<br>
                              error);<br>
     }<br>
<br>
-    transaction_complete_and_free (tr, error);<br>
+    transaction_task_complete_and_<wbr>free (task, error);<br>
     g_error_free (error);<br>
<br>
-    return FALSE;<br>
+    return G_SOURCE_REMOVE;<br>
 }<br>
<br>
 static void<br>
 transaction_cancelled (GCancellable           *cancellable,<br>
-                       TransactionWaitContext *ctx)<br>
+                       TransactionWaitContext *wait_ctx)<br>
 {<br>
-    Transaction *tr;<br>
-    GError *error = NULL;<br>
+    GTask              *task;<br>
+    TransactionContext *ctx;<br>
+    GError             *error = NULL;<br>
<br>
-    tr = device_release_transaction (ctx->self,<br>
-                                     ctx->type,<br>
-                                     MBIM_MESSAGE_TYPE_INVALID,<br>
-                                     ctx->transaction_id);<br>
+    task = device_release_transaction (wait_ctx->self,<br>
+                                       wait_ctx->type,<br>
+                                       MBIM_MESSAGE_TYPE_INVALID,<br>
+                                       wait_ctx->transaction_id);<br>
<br>
     /* The transaction may have already been cancelled before we stored it in<br>
      * the tracking table */<br>
-    if (!tr)<br>
+    if (!task)<br>
         return;<br>
<br>
-    tr->cancellable_id = 0;<br>
+    ctx = g_task_get_task_data (task);<br>
+    ctx->cancellable_id = 0;<br>
<br>
     /* Complete transaction with an abort error */<br>
     error = g_error_new (MBIM_CORE_ERROR,<br>
                          MBIM_CORE_ERROR_ABORTED,<br>
                          "Transaction aborted");<br>
-    transaction_complete_and_free (tr, error);<br>
+    transaction_task_complete_and_<wbr>free (task, error);<br>
     g_error_free (error);<br>
 }<br>
<br>
 static gboolean<br>
 device_store_transaction (MbimDevice       *self,<br>
                           TransactionType   type,<br>
-                          Transaction      *tr,<br>
+                          GTask            *task,<br>
                           guint             timeout_ms,<br>
                           GError          **error)<br>
 {<br>
-    trace_transaction (tr, "store");<br>
+    TransactionContext *ctx;<br>
+    GCancellable       *cancellable;<br>
+<br>
+    transaction_task_trace (task, "store");<br>
<br>
     if (G_UNLIKELY (!self->priv->transactions[<wbr>type]))<br>
         self->priv->transactions[type] = g_hash_table_new (g_direct_hash, g_direct_equal);<br>
<br>
-    tr->wait_ctx = g_slice_new (TransactionWaitContext);<br>
-    tr->wait_ctx->self = self;<br>
+    ctx = g_task_get_task_data (task);<br>
+<br>
+    ctx->wait_ctx = g_slice_new (TransactionWaitContext);<br>
+    ctx->wait_ctx->self = self;<br>
      /* valid as long as the transaction is in the HT */<br>
-    tr->wait_ctx->transaction_id = tr->transaction_id;<br>
-    tr->wait_ctx->type = type;<br>
+    ctx->wait_ctx->transaction_id = ctx->transaction_id;<br>
+    ctx->wait_ctx->type = type;<br>
<br>
     /* don't add timeout if one already exists */<br>
-    if (!tr->timeout_source) {<br>
-        tr->timeout_source = g_timeout_source_new (timeout_ms);<br>
-        g_source_set_callback (tr->timeout_source, (GSourceFunc)transaction_<wbr>timed_out, tr->wait_ctx, NULL);<br>
-        g_source_attach (tr->timeout_source, g_main_context_get_thread_<wbr>default ());<br>
-        g_source_unref (tr->timeout_source);<br>
+    if (!ctx->timeout_source) {<br>
+        ctx->timeout_source = g_timeout_source_new (timeout_ms);<br>
+        g_source_set_callback (ctx->timeout_source, (GSourceFunc)transaction_<wbr>timed_out, ctx->wait_ctx, NULL);<br>
+        g_source_attach (ctx->timeout_source, g_main_context_get_thread_<wbr>default ());<br>
+        g_source_unref (ctx->timeout_source);<br>
     }<br>
<br>
-    if (tr->cancellable && !tr->cancellable_id) {<br>
+    /* Indication transactions don't have cancellable */<br>
+    cancellable = g_task_get_cancellable (task);<br>
+    if (cancellable && !ctx->cancellable_id) {<br>
         /* Note: transaction_cancelled() will also be called directly if the<br>
          * cancellable is already cancelled */<br>
-        tr->cancellable_id = g_cancellable_connect (tr->cancellable,<br>
-                                                    (GCallback)transaction_<wbr>cancelled,<br>
-                                                    tr->wait_ctx,<br>
-                                                    NULL);<br>
-        if (!tr->cancellable_id) {<br>
+        ctx->cancellable_id = g_cancellable_connect (cancellable,<br>
+                                                     (GCallback)transaction_<wbr>cancelled,<br>
+                                                     ctx->wait_ctx,<br>
+                                                     NULL);<br>
+        if (!ctx->cancellable_id) {<br>
             g_set_error_literal (error,<br>
                                  MBIM_CORE_ERROR,<br>
                                  MBIM_CORE_ERROR_ABORTED,<br>
@@ -369,7 +393,7 @@ device_store_transaction (MbimDevice       *self,<br>
     }<br>
<br>
     /* Keep in the HT */<br>
-    g_hash_table_insert (self->priv->transactions[<wbr>type], GUINT_TO_POINTER (tr->transaction_id), tr);<br>
+    g_hash_table_insert (self->priv->transactions[<wbr>type], GUINT_TO_POINTER (ctx->transaction_id), task);<br>
<br>
     return TRUE;<br>
 }<br>
@@ -472,7 +496,7 @@ indication_ready (MbimDevice   *self,<br>
     GError *error = NULL;<br>
     MbimMessage *indication;<br>
<br>
-    if (g_simple_async_result_<wbr>propagate_error (G_SIMPLE_ASYNC_RESULT (res), &error)) {<br>
+    if (!(indication = g_task_propagate_pointer (G_TASK (res), &error))) {<br>
         g_debug ("[%s] Error processing indication message: %s",<br>
                  self->priv->path_display,<br>
                  error->message);<br>
@@ -480,8 +504,8 @@ indication_ready (MbimDevice   *self,<br>
         return;<br>
     }<br>
<br>
-    indication = g_simple_async_result_get_op_<wbr>res_gpointer (G_SIMPLE_ASYNC_RESULT (res));<br>
     g_signal_emit (self, signals[SIGNAL_INDICATE_<wbr>STATUS], 0, indication);<br>
+    mbim_message_unref (indication);<br>
 }<br>
<br>
 static void<br>
@@ -523,32 +547,33 @@ process_message (MbimDevice  *self,<br>
     case MBIM_MESSAGE_TYPE_CLOSE_DONE:<br>
     case MBIM_MESSAGE_TYPE_COMMAND_<wbr>DONE:<br>
     case MBIM_MESSAGE_TYPE_INDICATE_<wbr>STATUS: {<br>
-        GError *error = NULL;<br>
-        Transaction *tr;<br>
+        GError             *error = NULL;<br>
+        GTask              *task;<br>
+        TransactionContext *ctx;<br></blockquote><div><br></div><div>[Ben] we may as well do `ctx = g_task_get_task_data (task);` here instead of the two assignments below.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
         if (MBIM_MESSAGE_GET_MESSAGE_TYPE (message) == MBIM_MESSAGE_TYPE_INDICATE_<wbr>STATUS) {<br>
             /* Grab transaction */<br>
-            tr = device_release_transaction (self,<br>
-                                             TRANSACTION_TYPE_MODEM,<br>
-                                             MBIM_MESSAGE_TYPE_INDICATE_<wbr>STATUS,<br>
-                                             mbim_message_get_transaction_<wbr>id (message));<br>
+            task = device_release_transaction (self,<br>
+                                               TRANSACTION_TYPE_MODEM,<br>
+                                               MBIM_MESSAGE_TYPE_INDICATE_<wbr>STATUS,<br>
+                                               mbim_message_get_transaction_<wbr>id (message));<br>
<br>
-            if (!tr)<br>
+            if (!task)<br>
                 /* Create new transaction for the indication */<br>
-                tr = transaction_new (self,<br>
-                                      MBIM_MESSAGE_TYPE_INDICATE_<wbr>STATUS,<br>
-                                      mbim_message_get_transaction_<wbr>id (message),<br>
-                                      NULL, /* no cancellable */<br>
-                                      (GAsyncReadyCallback)<wbr>indication_ready,<br>
-                                      NULL);<br>
+                task = transaction_task_new (self,<br>
+                                             MBIM_MESSAGE_TYPE_INDICATE_<wbr>STATUS,<br>
+                                             mbim_message_get_transaction_<wbr>id (message),<br>
+                                             NULL, /* no cancellable */<br>
+                                             (GAsyncReadyCallback) indication_ready,<br>
+                                             NULL);<br>
         } else {<br>
             /* Grab transaction. This is a _DONE message, so look for the request<br>
              * that generated the _DONE */<br>
-            tr = device_release_transaction (self,<br>
-                                             TRANSACTION_TYPE_HOST,<br>
-                                             (MBIM_MESSAGE_GET_MESSAGE_TYPE (message) - 0x80000000),<br>
-                                             mbim_message_get_transaction_<wbr>id (message));<br>
-            if (!tr) {<br>
+            task = device_release_transaction (self,<br>
+                                               TRANSACTION_TYPE_HOST,<br>
+                                               (MBIM_MESSAGE_GET_MESSAGE_TYPE (message) - 0x80000000),<br>
+                                               mbim_message_get_transaction_<wbr>id (message));<br>
+            if (!task) {<br>
                 gchar *printable;<br>
<br>
                 g_debug ("[%s] No transaction matched in received message",<br>
@@ -566,65 +591,65 @@ process_message (MbimDevice  *self,<br>
<br>
             /* If the message doesn't have fragments, we're done */<br>
             if (!_mbim_message_is_fragment (message)) {<br>
-                g_assert (tr->fragments == NULL);<br>
-                tr->fragments = mbim_message_dup (message);<br>
-                transaction_complete_and_free (tr, NULL);<br>
+                ctx = g_task_get_task_data (task);<br>
+                g_assert (ctx->fragments == NULL);<br>
+                ctx->fragments = mbim_message_dup (message);<br>
+                transaction_task_complete_and_<wbr>free (task, NULL);<br>
                 return;<br>
             }<br>
         }<br>
<br>
         /* More than one fragment expected; is this the first one? */<br>
-        if (!tr->fragments)<br>
-            tr->fragments = _mbim_message_fragment_<wbr>collector_init (message, &error);<br>
+        ctx = g_task_get_task_data (task);<br>
+        if (!ctx->fragments)<br>
+            ctx->fragments = _mbim_message_fragment_<wbr>collector_init (message, &error);<br>
         else<br>
-            _mbim_message_fragment_<wbr>collector_add (tr->fragments, message, &error);<br>
+            _mbim_message_fragment_<wbr>collector_add (ctx->fragments, message, &error);<br>
<br>
         if (error) {<br>
-            device_report_error (self,<br>
-                                 tr->transaction_id,<br>
-                                 error);<br>
-            transaction_complete_and_free (tr, error);<br>
+            device_report_error (self, ctx->transaction_id, error);<br>
+            transaction_task_complete_and_<wbr>free (task, error);<br>
             g_error_free (error);<br>
             return;<br>
         }<br>
<br>
         /* Did we get all needed fragments? */<br>
-        if (_mbim_message_fragment_<wbr>collector_complete (tr->fragments)) {<br>
+        if (_mbim_message_fragment_<wbr>collector_complete (ctx->fragments)) {<br>
             /* Now, translate the whole message */<br>
             if (mbim_utils_get_traces_enabled ()) {<br>
                 gchar *printable;<br>
<br>
-                printable = mbim_message_get_printable (tr->fragments, ">>>>>> ", FALSE);<br>
+                printable = mbim_message_get_printable (ctx->fragments, ">>>>>> ", FALSE);<br>
                 g_debug ("[%s] Received message (translated)...\n%s",<br>
                          self->priv->path_display,<br>
                          printable);<br>
                 g_free (printable);<br>
             }<br>
<br>
-            transaction_complete_and_free (tr, NULL);<br>
+            transaction_task_complete_and_<wbr>free (task, NULL);<br>
             return;<br>
         }<br>
<br>
         /* Need more fragments, store transaction */<br>
         g_assert (device_store_transaction (self,<br>
                                             TRANSACTION_TYPE_HOST,<br>
-                                            tr,<br>
+                                            task,<br>
                                             MAX_TIME_BETWEEN_FRAGMENTS_MS,<br>
                                             NULL));<br>
         return;<br>
     }<br>
<br>
     case MBIM_MESSAGE_TYPE_FUNCTION_<wbr>ERROR: {<br>
-        Transaction *tr;<br>
         GError *error_indication;<br>
+        GTask  *task;<br>
<br>
         /* Try to match this transaction just per transaction ID */<br>
-        tr = device_release_transaction (self,<br>
-                                         TRANSACTION_TYPE_HOST,<br>
-                                         MBIM_MESSAGE_TYPE_INVALID,<br>
-                                         mbim_message_get_transaction_<wbr>id (message));<br>
+        task = device_release_transaction (self,<br>
+                                           TRANSACTION_TYPE_HOST,<br>
+                                           MBIM_MESSAGE_TYPE_INVALID,<br>
+                                           mbim_message_get_transaction_<wbr>id (message));<br>
<br>
-        if (!tr)<br>
+        if (!task)<br>
             g_debug ("[%s] No transaction matched in received function error message",<br>
                      self->priv->path_display);<br>
<br>
@@ -638,11 +663,15 @@ process_message (MbimDevice  *self,<br>
             g_free (printable);<br>
         }<br>
<br>
-        if (tr) {<br>
-            if (tr->fragments)<br>
-                mbim_message_unref (tr->fragments);<br>
-            tr->fragments = mbim_message_dup (message);<br>
-            transaction_complete_and_free (tr, NULL);<br>
+        if (task) {<br>
+            TransactionContext *ctx;<br>
+<br>
+            ctx = g_task_get_task_data (task);<br>
+<br>
+            if (ctx->fragments)<br>
+                mbim_message_unref (ctx->fragments);<br>
+            ctx->fragments = mbim_message_dup (message);<br>
+            transaction_task_complete_and_<wbr>free (task, NULL);<br>
         }<br>
<br>
         /* Signals are emitted regardless of whether the transaction matched or not */<br>
@@ -1983,11 +2012,7 @@ mbim_device_command_finish (MbimDevice    *self,<br>
                             GAsyncResult  *res,<br>
                             GError       **error)<br>
 {<br>
-    if (g_simple_async_result_<wbr>propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))<br>
-        return NULL;<br>
-<br>
-    return mbim_message_ref (g_simple_async_result_get_op_<wbr>res_gpointer (<br>
-                                 G_SIMPLE_ASYNC_RESULT (res)));<br>
+    return g_task_propagate_pointer (G_TASK (res), error);<br>
 }<br>
<br>
 /**<br>
@@ -2012,9 +2037,9 @@ mbim_device_command (MbimDevice          *self,<br>
                      GAsyncReadyCallback  callback,<br>
                      gpointer             user_data)<br>
 {<br>
-    GError *error = NULL;<br>
-    Transaction *tr;<br>
-    guint32 transaction_id;<br>
+    GError  *error = NULL;<br>
+    GTask   *task;<br>
+    guint32  transaction_id;<br>
<br>
     g_return_if_fail (MBIM_IS_DEVICE (self));<br>
     g_return_if_fail (message != NULL);<br>
@@ -2027,38 +2052,38 @@ mbim_device_command (MbimDevice          *self,<br>
         mbim_message_set_transaction_<wbr>id (message, transaction_id);<br>
     }<br>
<br>
-    tr = transaction_new (self,<br>
-                          MBIM_MESSAGE_GET_MESSAGE_TYPE (message),<br>
-                          transaction_id,<br>
-                          cancellable,<br>
-                          callback,<br>
-                          user_data);<br>
+    task = transaction_task_new (self,<br>
+                                 MBIM_MESSAGE_GET_MESSAGE_TYPE (message),<br>
+                                 transaction_id,<br>
+                                 cancellable,<br>
+                                 callback,<br>
+                                 user_data);<br>
<br>
     /* Device must be open */<br>
     if (!self->priv->iochannel) {<br>
         error = g_error_new (MBIM_CORE_ERROR,<br>
                              MBIM_CORE_ERROR_WRONG_STATE,<br>
                              "Device must be open to send commands");<br>
-        transaction_complete_and_free (tr, error);<br>
+        transaction_task_complete_and_<wbr>free (task, error);<br>
         g_error_free (error);<br>
         return;<br>
     }<br>
<br>
     /* Setup context to match response */<br>
-    if (!device_store_transaction (self, TRANSACTION_TYPE_HOST, tr, timeout * 1000, &error)) {<br>
+    if (!device_store_transaction (self, TRANSACTION_TYPE_HOST, task, timeout * 1000, &error)) {<br>
         g_prefix_error (&error, "Cannot store transaction: ");<br>
-        transaction_complete_and_free (tr, error);<br>
+        transaction_task_complete_and_<wbr>free (task, error);<br>
         g_error_free (error);<br>
         return;<br>
     }<br>
<br>
     if (!device_send (self, message, &error)) {<br>
         /* Match transaction so that we remove it from our tracking table */<br>
-        tr = device_release_transaction (self,<br>
-                                         TRANSACTION_TYPE_HOST,<br>
-                                         MBIM_MESSAGE_GET_MESSAGE_TYPE (message),<br>
-                                         mbim_message_get_transaction_<wbr>id (message));<br>
-        transaction_complete_and_free (tr, error);<br>
+        task = device_release_transaction (self,<br>
+                                           TRANSACTION_TYPE_HOST,<br>
+                                           MBIM_MESSAGE_GET_MESSAGE_TYPE (message),<br>
+                                           mbim_message_get_transaction_<wbr>id (message));<br>
+        transaction_task_complete_and_<wbr>free (task, error);<br>
         g_error_free (error);<br>
         return;<br>
     }<br>
<span class="gmail-HOEnZb"><font color="#888888">--<br>
2.14.1<br>
<br>
______________________________<wbr>_________________<br>
libmbim-devel mailing list<br>
<a href="mailto:libmbim-devel@lists.freedesktop.org">libmbim-devel@lists.<wbr>freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/libmbim-devel" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/libmbim-devel</a><br>
</font></span></blockquote></div><br></div></div>