summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabiano Fidêncio <fidencio@redhat.com>2016-03-22 20:01:59 +0100
committerFabiano Fidêncio <fidencio@redhat.com>2016-03-22 23:00:33 +0100
commite81d97cc00558e5af087b65e52acb55bbfcdc01b (patch)
tree2cca9b038bad205f8c2c1606c6094b5c10e00ec4
parent5b008c35c3edb29f82dfb458241570ca60a08a91 (diff)
downloadspice-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.c29
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);
}