diff options
author | Fabiano Fidêncio <fidencio@redhat.com> | 2016-03-22 20:01:59 +0100 |
---|---|---|
committer | Fabiano Fidêncio <fidencio@redhat.com> | 2016-03-22 23:00:33 +0100 |
commit | e81d97cc00558e5af087b65e52acb55bbfcdc01b (patch) | |
tree | 2cca9b038bad205f8c2c1606c6094b5c10e00ec4 | |
parent | 5b008c35c3edb29f82dfb458241570ca60a08a91 (diff) | |
download | spice-gtk-e81d97cc00558e5af087b65e52acb55bbfcdc01b.tar.gz spice-gtk-e81d97cc00558e5af087b65e52acb55bbfcdc01b.tar.xz spice-gtk-e81d97cc00558e5af087b65e52acb55bbfcdc01b.zip |
vmcstream,gtask: Do idle ourself instead of leaving it to GTask's heuristic
Seems that GTask heuristic only makes sense in a non-coroutine case.
After opening a bug[0] on spice-gtk and a few discussions in the mailing
list, seems that is completely fine for coroutine code to deal with the
idle explicitly.
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
Acked-by: Marc-André Lureau <mlureau@redhat.com>
-rw-r--r-- | src/vmcstream.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/src/vmcstream.c b/src/vmcstream.c index 5ebf15a..5dd2799 100644 --- a/src/vmcstream.c +++ b/src/vmcstream.c @@ -97,6 +97,24 @@ spice_vmc_input_stream_new(void) return self; } +typedef struct _complete_in_idle_cb_data { + GTask *task; + gssize pos; +} complete_in_idle_cb_data; + +static gboolean +complete_in_idle_cb(gpointer user_data) +{ + complete_in_idle_cb_data *data = user_data; + + g_task_return_int(data->task, data->pos); + + g_object_unref (data->task); + g_free (data); + + return FALSE; +} + /* coroutine */ /** * Feed a SpiceVmc stream with new data from a coroutine @@ -116,6 +134,8 @@ spice_vmc_input_stream_co_data(SpiceVmcInputStream *self, self->coroutine = coroutine_self(); while (size > 0) { + complete_in_idle_cb_data *cb_data; + SPICE_DEBUG("spicevmc co_data %p", self->task); if (!self->task) coroutine_yield(NULL); @@ -137,10 +157,15 @@ spice_vmc_input_stream_co_data(SpiceVmcInputStream *self, if (self->all && min > 0 && self->pos != self->count) continue; - g_task_return_int(self->task, self->pos); + /* Let's deal with the task complete in idle by ourselves, as GTask + * heuristic only makes sense in a non-coroutine case. + */ + cb_data = g_new(complete_in_idle_cb_data , 1); + cb_data->task = g_object_ref(self->task); + cb_data->pos = self->pos; + g_idle_add(complete_in_idle_cb, cb_data); g_cancellable_disconnect(g_task_get_cancellable(self->task), self->cancel_id); - g_clear_object(&self->task); } |