[Spice-devel] [PATCH 08/14] spice-pulse: Use GTask instead of GSimpleAsyncResult

Fabiano FidĂȘncio fidencio at redhat.com
Wed Jan 20 07:09:44 PST 2016


On Mon, Jan 18, 2016 at 2:55 PM, Christophe Fergeau <cfergeau at redhat.com> wrote:
> On Mon, Jan 18, 2016 at 10:05:44AM +0100, Fabiano FidĂȘncio wrote:
>> Instead of using GSimpleAsyncResult, use the new GTask API, which is
>> much more straightforward.
>> ---
>>  src/spice-pulse.c | 96 +++++++++++++++++++------------------------------------
>>  1 file changed, 33 insertions(+), 63 deletions(-)
>>
>> diff --git a/src/spice-pulse.c b/src/spice-pulse.c
>> index 22db893..60a037c 100644
>> --- a/src/spice-pulse.c
>> +++ b/src/spice-pulse.c
>> @@ -34,13 +34,12 @@
>>  struct async_task {
>>      SpicePulse                 *pulse;
>>      SpiceMainChannel           *main_channel;
>> -    GSimpleAsyncResult         *res;
>> +    GTask                      *task;
>>      GAsyncReadyCallback        callback;
>>      gpointer                   user_data;
>>      gboolean                   is_playback;
>>      pa_operation               *pa_op;
>>      gulong                     cancel_id;
>> -    GCancellable               *cancellable;
>>  };
>>
>>  struct stream {
>> @@ -941,8 +940,8 @@ static gboolean free_async_task(gpointer user_data)
>>          g_object_unref(task->pulse);
>>      }
>>
>> -    if (task->res)
>> -        g_object_unref(task->res);
>> +    if (task->task)
>> +        g_object_unref(task->task);
>>
>>      if (task->main_channel)
>>          g_object_unref(task->main_channel);
>> @@ -950,10 +949,9 @@ static gboolean free_async_task(gpointer user_data)
>>      if (task->pa_op != NULL)
>>          pa_operation_unref(task->pa_op);
>>
>> -    if (task->cancel_id != 0) {
>> -        g_cancellable_disconnect(task->cancellable, task->cancel_id);
>> -        g_clear_object(&task->cancellable);
>> -    }
>> +    if (task->cancel_id != 0)
>> +        g_cancellable_disconnect(g_task_get_cancellable(task->task),
>> +                                 task->cancel_id);
>
> You need to move the g_object_unref(task->task) after this.
>
>>
>>      g_free(task);
>>      return G_SOURCE_REMOVE;
>> @@ -981,14 +979,6 @@ static void cancel_task(GCancellable *cancellable, gpointer user_data)
>>          task->pulse->priv->pending_restore_task = NULL;
>>      }
>>
>> -#if !GLIB_CHECK_VERSION(2,32,0)
>> -    /* g_simple_async_result_set_check_cancellable is not present. Set an error
>> -     * in the GSimpleAsyncResult in case of _finish functions is called */
>> -    g_simple_async_result_set_error(task->res,
>> -                                    SPICE_CLIENT_ERROR,
>> -                                    SPICE_CLIENT_ERROR_FAILED,
>> -                                    "Operation was cancelled");
>> -#endif
>>      /* FIXME: https://bugzilla.gnome.org/show_bug.cgi?id=705395
>>       * Free the memory in idle */
>>      g_idle_add(free_async_task, task);
>> @@ -1001,27 +991,23 @@ static void complete_task(SpicePulse *pulse, struct async_task *task, const gcha
>>
>>      /* If we do have any err_msg, we failed */
>>      if (err_msg != NULL) {
>> -        g_simple_async_result_set_op_res_gboolean(task->res, FALSE);
>> -        g_simple_async_result_set_error(task->res,
>> -                                        SPICE_CLIENT_ERROR,
>> -                                        SPICE_CLIENT_ERROR_FAILED,
>> -                                        "restore-info failed due %s",
>> -                                        err_msg);
>> +        g_task_return_boolean(task->task, FALSE);
>
> This can be removed.
>
>> +        g_task_return_new_error(task->task,
>> +                                SPICE_CLIENT_ERROR,
>> +                                SPICE_CLIENT_ERROR_FAILED,
>> +                                "restore-info failed due %s",
>> +                                err_msg);
>>      /* Volume-info does not change if stream is not found */
>>      } else if ((task->is_playback == TRUE && p->playback.info_updated == FALSE) ||
>>                 (task->is_playback == FALSE && p->record.info_updated == FALSE)) {
>> -        g_simple_async_result_set_op_res_gboolean(task->res, FALSE);
>> -        g_simple_async_result_set_error(task->res,
>> -                                        SPICE_CLIENT_ERROR,
>> -                                        SPICE_CLIENT_ERROR_FAILED,
>> -                                        "Stream not found by pulse");
>> +        g_task_return_boolean(task->task, FALSE);
>
> This can be removed too.
>
>> +        g_task_return_new_error(task->task,
>> +                                SPICE_CLIENT_ERROR,
>> +                                SPICE_CLIENT_ERROR_FAILED,
>> +                                "Stream not found by pulse");
>>      } else {
>> -        g_simple_async_result_set_op_res_gboolean(task->res, TRUE);
>> +        g_task_return_boolean(task->task, TRUE);
>>      }
>> -
>> -    /* As all async calls to PulseAudio are done with glib mainloop, it is
>> -     * safe to complete the operation synchronously here. */
>> -    g_simple_async_result_complete(task->res);
>>  }
>>
>>  static void spice_pulse_complete_async_task(struct async_task *task, const gchar *err_msg)
>> @@ -1157,19 +1143,13 @@ static void pulse_stream_restore_info_async(gboolean is_playback,
>>                                              gpointer user_data)
>>  {
>>      SpicePulsePrivate *p = SPICE_PULSE(audio)->priv;
>> -    GSimpleAsyncResult *simple;
>> +    GTask *res;
>
> Usually you call it 'task' in this series, not 'res'

Yep. But take a look on line below this one. 'task' is already being used.
If you prefer, I can change it to 'task' and also change the 'task' to
something else ....

>
>>      struct async_task *task = g_malloc0(sizeof(struct async_task));
>>      pa_operation *op = NULL;
>>
>> -    simple = g_simple_async_result_new(G_OBJECT(audio),
>> -                                       callback,
>> -                                       user_data,
>> -                                       pulse_stream_restore_info_async);
>> -#if GLIB_CHECK_VERSION(2,32,0)
>> -    g_simple_async_result_set_check_cancellable (simple, cancellable);
>> -#endif
>> +    res = g_task_new(audio, cancellable, callback, user_data);
>>
>> -    task->res = simple;
>> +    task->task = res;
>>      task->pulse = g_object_ref(audio);
>>      task->callback = callback;
>>      task->user_data = user_data;
>> @@ -1177,10 +1157,8 @@ static void pulse_stream_restore_info_async(gboolean is_playback,
>>      task->main_channel = g_object_ref(main_channel);
>>      task->pa_op = NULL;
>>
>> -    if (cancellable) {
>> -        task->cancellable = g_object_ref(cancellable);
>> +    if (cancellable)
>>          task->cancel_id = g_cancellable_connect(cancellable, G_CALLBACK(cancel_task), task, NULL);
>> -    }
>>
>>      /* If Playback/Record stream is created we use pulse API to get volume-info
>>       * from those streams directly. If the stream is not created, retrieve last
>> @@ -1257,13 +1235,14 @@ static void pulse_stream_restore_info_async(gboolean is_playback,
>>
>>  fail:
>>      if (!op) {
>> -        g_simple_async_report_error_in_idle(G_OBJECT(audio),
>> -                                            callback,
>> -                                            user_data,
>> -                                            SPICE_CLIENT_ERROR,
>> -                                            SPICE_CLIENT_ERROR_FAILED,
>> -                                            "Volume-Info failed: %s",
>> -                                            pa_strerror(pa_context_errno(p->context)));
>> +        g_task_report_new_error(audio,
>> +                                callback,
>> +                                user_data,
>> +                                pulse_stream_restore_info_async,
>> +                                SPICE_CLIENT_ERROR,
>> +                                SPICE_CLIENT_ERROR_FAILED,
>> +                                "Volume-Info failed: %s",
>> +                                pa_strerror(pa_context_errno(p->context)));
>>          free_async_task(task);
>>      }
>>  }
>> @@ -1279,18 +1258,9 @@ static gboolean pulse_stream_restore_info_finish(gboolean is_playback,
>>  {
>>      SpicePulsePrivate *p = SPICE_PULSE(audio)->priv;
>>      struct stream *pstream = (is_playback) ? &p->playback : &p->record;
>> -    GSimpleAsyncResult *simple = (GSimpleAsyncResult *) res;
>> -
>> -    g_return_val_if_fail(g_simple_async_result_is_valid(res,
>> -        G_OBJECT(audio), pulse_stream_restore_info_async), FALSE);
>> +    GTask *task = G_TASK(res);
>>
>> -    if (g_simple_async_result_propagate_error(simple, error)) {
>> -        /* set out args that should have new alloc'ed memory to NULL */
>> -        if (volume != NULL) {
>> -            *volume = NULL;
>> -        }
>
> I would keep this and the return early when there has been an error.
>
>> -        return FALSE;
>> -    }
>> +    g_return_val_if_fail(g_task_is_valid(task, G_OBJECT(audio)), FALSE);
>>
>>      if (mute != NULL) {
>>          *mute = (pstream->info.mute) ? TRUE : FALSE;
>> @@ -1310,7 +1280,7 @@ static gboolean pulse_stream_restore_info_finish(gboolean is_playback,
>>          }
>>      }
>>
>> -    return g_simple_async_result_get_op_res_gboolean(simple);
>> +    return g_task_propagate_boolean(task, error);
>>  }
>>
>>  static void spice_pulse_get_playback_volume_info_async(SpiceAudio *audio,
>> --
>> 2.5.0
>>
>> _______________________________________________
>> Spice-devel mailing list
>> Spice-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/spice-devel


More information about the Spice-devel mailing list