summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Fergeau <cfergeau@redhat.com>2013-11-15 16:03:17 +0100
committerChristophe Fergeau <cfergeau@redhat.com>2013-11-18 15:03:18 +0100
commit143afbb8851a114397692f4ae0334d439af77637 (patch)
tree678c5e921ac7dd224647dfbf34da4cd13efb9ba0
parent812c85b21bc1b9eeb0ff5c5659da53bc64786af0 (diff)
Fix IN_MAIN_CONTEXT when using coroutine=gthread
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.
-rw-r--r--gtk/coroutine.h4
-rw-r--r--gtk/coroutine_gthread.c4
-rw-r--r--gtk/coroutine_ucontext.c5
-rw-r--r--gtk/coroutine_winfibers.c5
4 files changed, 17 insertions, 1 deletions
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 51d2d6f..ab30631 100644
--- a/gtk/coroutine_gthread.c
+++ b/gtk/coroutine_gthread.c
@@ -160,3 +160,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 889f0d6..f960cfb 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 f4a4481..266b1de 100644
--- a/gtk/coroutine_winfibers.c
+++ b/gtk/coroutine_winfibers.c
@@ -111,6 +111,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