From 24187e7179c7bf37187b0c06e85fa867810fa00a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Mon, 9 Jan 2012 14:23:21 +0100 Subject: [PATCH spice-gtk] Create a GCoroutine, get rid of wait_queue https://bugs.freedesktop.org/show_bug.cgi?id=44570 --- gtk/gio-coroutine.c | 24 ++++++++++++------------ gtk/gio-coroutine.h | 10 ++++++---- gtk/spice-channel-priv.h | 3 +-- gtk/spice-channel.c | 8 ++++---- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/gtk/gio-coroutine.c b/gtk/gio-coroutine.c index 5c9621d..704b5ac 100644 --- a/gtk/gio-coroutine.c +++ b/gtk/gio-coroutine.c @@ -53,26 +53,24 @@ GIOCondition g_io_wait(GSocket *sock, GIOCondition cond) } -GIOCondition g_io_wait_interruptible(struct wait_queue *wait, +GIOCondition g_io_wait_interruptible(GCoroutine *self, GSocket *sock, GIOCondition cond) { GIOCondition *ret; gint id; - g_return_val_if_fail(wait != NULL, 0); + g_return_val_if_fail(self != NULL, 0); g_return_val_if_fail(sock != NULL, 0); - wait->context = coroutine_self(); GSource *src = g_socket_create_source(sock, cond | G_IO_HUP | G_IO_ERR | G_IO_NVAL, NULL); - g_source_set_callback(src, (GSourceFunc)g_io_wait_helper, - wait->context, NULL); + g_source_set_callback(src, (GSourceFunc)g_io_wait_helper, self, NULL); id = g_source_attach(src, NULL); - wait->waiting = TRUE; + self->waiting = TRUE; ret = coroutine_yield(NULL); - wait->waiting = FALSE; + self->waiting = FALSE; g_source_unref(src); if (ret == NULL) { @@ -82,10 +80,12 @@ GIOCondition g_io_wait_interruptible(struct wait_queue *wait, return *ret; } -void g_io_wakeup(struct wait_queue *wait) +void g_io_wakeup(GCoroutine *coroutine) { - if (wait->waiting) - coroutine_yieldto(wait->context, NULL); + g_return_if_fail(coroutine != NULL); + + if (coroutine->waiting) + coroutine_yieldto(&coroutine->coroutine, NULL); } @@ -124,8 +124,8 @@ GSourceFuncs waitFuncs = { static gboolean g_condition_wait_helper(gpointer data) { - struct coroutine *co = (struct coroutine *)data; - coroutine_yieldto(co, NULL); + GCoroutine *self = (GCoroutine *)data; + coroutine_yieldto(&self->coroutine, NULL); return FALSE; } diff --git a/gtk/gio-coroutine.h b/gtk/gio-coroutine.h index 26e447e..43dbc55 100644 --- a/gtk/gio-coroutine.h +++ b/gtk/gio-coroutine.h @@ -26,10 +26,12 @@ G_BEGIN_DECLS -struct wait_queue +typedef struct _GCoroutine GCoroutine; + +struct _GCoroutine { + struct coroutine coroutine; gboolean waiting; - struct coroutine *context; }; /* @@ -47,8 +49,8 @@ typedef void (*GSignalEmitMainFunc)(GObject *object, int signum, gpointer params GIOCondition g_io_wait (GSocket *sock, GIOCondition cond); gboolean g_condition_wait (GConditionWaitFunc func, gpointer data); -void g_io_wakeup (struct wait_queue *wait); -GIOCondition g_io_wait_interruptible(struct wait_queue *wait, GSocket *sock, GIOCondition cond); +void g_io_wakeup (GCoroutine *coroutine); +GIOCondition g_io_wait_interruptible(GCoroutine *coroutine, GSocket *sock, GIOCondition cond); void g_signal_emit_main_context(GObject *object, GSignalEmitMainFunc func, int signum, gpointer params, const char *debug_info); void g_object_notify_main_context(GObject *object, const gchar *property_name); diff --git a/gtk/spice-channel-priv.h b/gtk/spice-channel-priv.h index a3d1cd2..7fa005c 100644 --- a/gtk/spice-channel-priv.h +++ b/gtk/spice-channel-priv.h @@ -94,12 +94,11 @@ struct _SpiceChannelPrivate { /* not swapped */ SpiceSession *session; - struct coroutine coroutine; + GCoroutine coroutine; int fd; gboolean has_error; guint connect_delayed_id; - struct wait_queue wait; GQueue xmit_queue; gboolean xmit_queue_blocked; GStaticMutex xmit_queue_lock; diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c index 71c671e..5f698b9 100644 --- a/gtk/spice-channel.c +++ b/gtk/spice-channel.c @@ -1694,7 +1694,7 @@ void spice_channel_wakeup(SpiceChannel *channel) { SpiceChannelPrivate *c = channel->priv; - g_io_wakeup(&c->wait); + g_io_wakeup(&c->coroutine); } G_GNUC_INTERNAL @@ -2004,7 +2004,7 @@ static gboolean spice_channel_iterate(SpiceChannel *channel) } SPICE_CHANNEL_GET_CLASS(channel)->iterate_write(channel); - ret = g_io_wait_interruptible(&c->wait, c->sock, G_IO_IN); + ret = g_io_wait_interruptible(&c->coroutine, c->sock, G_IO_IN); #ifdef WIN32 /* FIXME: windows gsocket is buggy, it doesn't return correct condition... */ @@ -2042,7 +2042,7 @@ static gboolean spice_channel_delayed_unref(gpointer data) g_return_val_if_fail(channel != NULL, FALSE); SPICE_DEBUG("Delayed unref channel %s %p", c->name, channel); - g_return_val_if_fail(c->coroutine.exited == TRUE, FALSE); + g_return_val_if_fail(c->coroutine.coroutine.exited == TRUE, FALSE); g_object_unref(G_OBJECT(data)); @@ -2209,7 +2209,7 @@ static gboolean connect_delayed(gpointer data) SPICE_DEBUG("Open coroutine starting %p", channel); c->connect_delayed_id = 0; - co = &c->coroutine; + co = &c->coroutine.coroutine; co->stack_size = 16 << 20; /* 16Mb */ co->entry = spice_channel_coroutine; -- 1.7.7.5