[Spice-devel] [spice-gtk] Fix IN_MAIN_CONTEXT when using coroutine=gthread

Christophe Fergeau cfergeau at redhat.com
Fri Nov 15 07:05:55 PST 2013


The IN_MAIN_CONTEXT macro checks coroutine_self()->caller against NULL to
decide whether we are in the main context or not. However, this is an
implementation detail of the ucontext coroutine implementation, in the
gthread implementation, coroutine_self()->caller will be non-NULL even in
the main context.

This commit introduces a coroutine_is_main_context() method which each
coroutine backend implements. It turns out it can be implemented the same
way for each backend.
---
 gtk/coroutine.h           | 4 +++-
 gtk/coroutine_gthread.c   | 4 ++++
 gtk/coroutine_ucontext.c  | 5 +++++
 gtk/coroutine_winfibers.c | 5 +++++
 4 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/gtk/coroutine.h b/gtk/coroutine.h
index 7e3bc28..15b90b4 100644
--- a/gtk/coroutine.h
+++ b/gtk/coroutine.h
@@ -55,7 +55,7 @@ struct coroutine
 #endif
 };
 
-#define IN_MAIN_CONTEXT (coroutine_self() == NULL || coroutine_self()->caller == NULL)
+#define IN_MAIN_CONTEXT (coroutine_self() == NULL || coroutine_is_main_context(coroutine_self()))
 int coroutine_init(struct coroutine *co);
 
 int coroutine_release(struct coroutine *co);
@@ -68,6 +68,8 @@ void *coroutine_yieldto(struct coroutine *to, void *arg);
 
 void *coroutine_yield(void *arg);
 
+gboolean coroutine_is_main_context(struct coroutine *co);
+
 #endif
 /*
  * Local variables:
diff --git a/gtk/coroutine_gthread.c b/gtk/coroutine_gthread.c
index 14231a0..25f4afa 100644
--- a/gtk/coroutine_gthread.c
+++ b/gtk/coroutine_gthread.c
@@ -161,3 +161,7 @@ void *coroutine_yield(void *arg)
 	return coroutine_swap(coroutine_self(), to, arg);
 }
 
+gboolean coroutine_is_main_context(struct coroutine *co)
+{
+    return (co == &leader);
+}
diff --git a/gtk/coroutine_ucontext.c b/gtk/coroutine_ucontext.c
index af811a7..1a7c952 100644
--- a/gtk/coroutine_ucontext.c
+++ b/gtk/coroutine_ucontext.c
@@ -130,6 +130,11 @@ void *coroutine_yield(void *arg)
 	coroutine_self()->caller = NULL;
 	return coroutine_swap(coroutine_self(), to, arg);
 }
+
+gboolean coroutine_is_main_context(struct coroutine *co)
+{
+    return (co == &leader);
+}
 /*
  * Local variables:
  *  c-indent-level: 8
diff --git a/gtk/coroutine_winfibers.c b/gtk/coroutine_winfibers.c
index a4cd14b..6d2d8b5 100644
--- a/gtk/coroutine_winfibers.c
+++ b/gtk/coroutine_winfibers.c
@@ -112,6 +112,11 @@ void *coroutine_yield(void *arg)
 	coroutine_self()->caller = NULL;
 	return coroutine_swap(coroutine_self(), to, arg);
 }
+
+gboolean coroutine_is_main_context(struct coroutine *co)
+{
+    return (co == &leader);
+}
 /*
  * Local variables:
  *  c-indent-level: 8
-- 
1.8.4.2



More information about the Spice-devel mailing list