On Mon, Jan 18, 2016 at 10:05:47AM +0100, Fabiano Fidêncio wrote: > Instead of using GSimpleAsyncResult, use the new GTask API, which is > much more straightforward. > --- > src/vmcstream.c | 129 +++++++++++++++++++++++--------------------------------- > 1 file changed, 52 insertions(+), 77 deletions(-) > > diff --git a/src/vmcstream.c b/src/vmcstream.c > index 483dd5a..d9b62a0 100644 > --- a/src/vmcstream.c > +++ b/src/vmcstream.c > @@ -27,7 +27,7 @@ > struct _SpiceVmcInputStream > { > GInputStream parent_instance; > - GSimpleAsyncResult *result; > + GTask *task; > struct coroutine *coroutine; > > SpiceChannel *channel; > @@ -36,7 +36,6 @@ struct _SpiceVmcInputStream > gsize count; > gsize pos; > > - GCancellable *cancellable; > gulong cancel_id; > }; > > @@ -118,11 +117,12 @@ spice_vmc_input_stream_co_data(SpiceVmcInputStream *self, > self->coroutine = coroutine_self(); > > while (size > 0) { > - SPICE_DEBUG("spicevmc co_data %p", self->result); > - if (!self->result) > + GCancellable *cancellable; > + SPICE_DEBUG("spicevmc co_data %p", self->task); > + if (!self->task) > coroutine_yield(NULL); > > - g_return_if_fail(self->result != NULL); > + g_return_if_fail(self->task != NULL); > > gsize min = MIN(self->count, size); > memcpy(self->buffer, data, min); > @@ -139,14 +139,13 @@ spice_vmc_input_stream_co_data(SpiceVmcInputStream *self, > if (self->all && min > 0 && self->pos != self->count) > continue; > > - g_simple_async_result_set_op_res_gssize(self->result, self->pos); > + g_task_return_int(self->task, self->pos); > + > + cancellable = g_task_get_cancellable(self->task); > + if (cancellable) > + g_cancellable_disconnect(cancellable, self->cancel_id); > > - g_simple_async_result_complete_in_idle(self->result); > - g_clear_object(&self->result); > - if (self->cancellable) { > - g_cancellable_disconnect(self->cancellable, self->cancel_id); > - g_clear_object(&self->cancellable); > - } > + g_clear_object(&self->task); > } > > self->coroutine = NULL; > @@ -158,13 +157,12 @@ read_cancelled(GCancellable *cancellable, > { > SpiceVmcInputStream *self = SPICE_VMC_INPUT_STREAM(user_data); > > - SPICE_DEBUG("read cancelled, %p", self->result); > - g_simple_async_result_set_error(self->result, > - G_IO_ERROR, G_IO_ERROR_CANCELLED, > - "read cancelled"); > - g_simple_async_result_complete_in_idle(self->result); > + SPICE_DEBUG("read cancelled, %p", self->task); > + g_task_return_new_error(self->task, > + G_IO_ERROR, G_IO_ERROR_CANCELLED, > + "read cancelled"); > > - g_clear_object(&self->result); > + g_clear_object(&self->task); > > /* See FIXME */ > /* if (self->cancellable) { */ > @@ -183,21 +181,20 @@ spice_vmc_input_stream_read_all_async(GInputStream *stream, > gpointer user_data) > { > SpiceVmcInputStream *self = SPICE_VMC_INPUT_STREAM(stream); > - GSimpleAsyncResult *result; > + GTask *task; > > /* no concurrent read permitted by ginputstream */ > - g_return_if_fail(self->result == NULL); > - g_return_if_fail(self->cancellable == NULL); > + g_return_if_fail(self->task == NULL); > + g_return_if_fail(g_task_get_cancellable(self->task) == NULL); > self->all = TRUE; > self->buffer = buffer; > self->count = count; > self->pos = 0; > - result = g_simple_async_result_new(G_OBJECT(self), > - callback, > - user_data, > - spice_vmc_input_stream_read_async); > - self->result = result; > - self->cancellable = g_object_ref(cancellable); > + task = g_task_new(self, > + cancellable, > + callback, > + user_data); > + self->task = task; > if (cancellable) > self->cancel_id = > g_cancellable_connect(cancellable, G_CALLBACK(read_cancelled), self, NULL); > @@ -211,27 +208,19 @@ spice_vmc_input_stream_read_all_finish(GInputStream *stream, > GAsyncResult *result, > GError **error) > { > - GSimpleAsyncResult *simple; > + GTask *task = G_TASK(result); > + GCancellable *cancellable; > SpiceVmcInputStream *self = SPICE_VMC_INPUT_STREAM(stream); > > - g_return_val_if_fail(g_simple_async_result_is_valid(result, > - G_OBJECT(self), > - spice_vmc_input_stream_read_async), > - -1); > - > - simple = (GSimpleAsyncResult *)result; > + g_return_val_if_fail(g_task_is_valid(task, self), -1); > > /* FIXME: calling _finish() is required. Disconnecting in > read_cancelled() causes a deadlock. #705395 */ > - if (self->cancellable) { > - g_cancellable_disconnect(self->cancellable, self->cancel_id); > - g_clear_object(&self->cancellable); > - } > - > - if (g_simple_async_result_propagate_error(simple, error)) > - return -1; > + cancellable = g_task_get_cancellable(task); > + if (cancellable) > + g_cancellable_disconnect(cancellable, self->cancel_id); > > - return g_simple_async_result_get_op_res_gssize(simple); > + return g_task_propagate_int(task, error); > } > > static void > @@ -244,21 +233,18 @@ spice_vmc_input_stream_read_async(GInputStream *stream, > gpointer user_data) > { > SpiceVmcInputStream *self = SPICE_VMC_INPUT_STREAM(stream); > - GSimpleAsyncResult *result; > + GTask *task; > > /* no concurrent read permitted by ginputstream */ > - g_return_if_fail(self->result == NULL); > - g_return_if_fail(self->cancellable == NULL); > + g_return_if_fail(self->task == NULL); > + g_return_if_fail(g_task_get_cancellable(self->task) == NULL); > self->all = FALSE; > self->buffer = buffer; > self->count = count; > self->pos = 0; > - result = g_simple_async_result_new(G_OBJECT(self), > - callback, > - user_data, > - spice_vmc_input_stream_read_async); > - self->result = result; > - self->cancellable = g_object_ref(cancellable); > + > + task = g_task_new(self, cancellable, callback, user_data); > + self->task = task; > if (cancellable) > self->cancel_id = > g_cancellable_connect(cancellable, G_CALLBACK(read_cancelled), self, NULL); > @@ -272,27 +258,19 @@ spice_vmc_input_stream_read_finish(GInputStream *stream, > GAsyncResult *result, > GError **error) > { > - GSimpleAsyncResult *simple; > + GTask *task = G_TASK(result); > + GCancellable *cancellable; > SpiceVmcInputStream *self = SPICE_VMC_INPUT_STREAM(stream); > > - g_return_val_if_fail(g_simple_async_result_is_valid(result, > - G_OBJECT(self), > - spice_vmc_input_stream_read_async), > - -1); > - > - simple = (GSimpleAsyncResult *)result; > + g_return_val_if_fail(g_task_is_valid(task, self), -1); > > /* FIXME: calling _finish() is required. Disconnecting in > read_cancelled() causes a deadlock. #705395 */ > - if (self->cancellable) { > - g_cancellable_disconnect(self->cancellable, self->cancel_id); > - g_clear_object(&self->cancellable); > - } > - > - if (g_simple_async_result_propagate_error(simple, error)) > - return -1; > + cancellable = g_task_get_cancellable(task); > + if (cancellable) > + g_cancellable_disconnect(cancellable, self->cancel_id); > > - return g_simple_async_result_get_op_res_gssize(simple); > + return g_task_propagate_int(task, error); > } > > static gssize > @@ -407,11 +385,10 @@ spice_vmc_output_stream_write_finish(GOutputStream *stream, > GError **error) > { > SpiceVmcOutputStream *self = SPICE_VMC_OUTPUT_STREAM(stream); > - GSimpleAsyncResult *res = > - g_simple_async_result_get_op_res_gpointer(G_SIMPLE_ASYNC_RESULT(simple)); > + GAsyncResult *res = g_task_propagate_pointer(G_TASK(simple), error); > > SPICE_DEBUG("spicevmc write finish"); > - return spice_vmc_write_finish(self->channel, G_ASYNC_RESULT(res), error); > + return spice_vmc_write_finish(self->channel, res, error); > } > > static void > @@ -419,12 +396,11 @@ write_cb(GObject *source_object, > GAsyncResult *res, > gpointer user_data) > { > - GSimpleAsyncResult *simple = user_data; > + GTask *task = user_data; > > - g_simple_async_result_set_op_res_gpointer(simple, res, NULL); > + g_task_return_pointer(task, res, NULL); > > - g_simple_async_result_complete(simple); > - g_object_unref(simple); > + g_object_unref(task); As we have less control with GTask over whether g_task_return_pointer will call the callback immediatly or queue an idle, I'm wondering whether we should g_object_ref(res) in g_task_return_pointer() to be sure it's still alive in case we run in an idle (though more things may break if an idle is involved rather than a direct call). Christophe
Attachment:
signature.asc
Description: PGP signature
_______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel