summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPixel <pixel@nobis-crew.org>2011-12-01 08:23:59 -0800
committerPixel <pixel@nobis-crew.org>2011-12-01 09:09:56 -0800
commit348640078e3d991421c6535f3528f6c351ec2922 (patch)
tree9b71f1c716a222e2ce80970085cc18debd92bbc6
parent128d4e8c4a9103fe5a02682de89c6a660ff2a5d3 (diff)
Adding the CORO_SJLJ_PTHREAD target, to be pthread-compliant when doing the SJLJ method.HEADmaster
-rw-r--r--coro.c26
-rw-r--r--coro.h4
2 files changed, 23 insertions, 7 deletions
diff --git a/coro.c b/coro.c
index 615af83..b44c8b0 100644
--- a/coro.c
+++ b/coro.c
@@ -45,7 +45,7 @@
/*****************************************************************************/
/* ucontext/setjmp/asm backends */
/*****************************************************************************/
-#if CORO_UCONTEXT || CORO_SJLJ || CORO_LOSER || CORO_LINUX || CORO_IRIX || CORO_ASM
+#if CORO_UCONTEXT || CORO_SJLJ || CORO_SJLJ_PTHREAD || CORO_LOSER || CORO_LINUX || CORO_IRIX || CORO_ASM
# if CORO_UCONTEXT
# include <stddef.h>
@@ -70,7 +70,7 @@
# include <stdlib.h>
-# if CORO_SJLJ
+# if CORO_SJLJ || CORO_SJLJ_PTHREAD
# include <stdio.h>
# include <signal.h>
# include <unistd.h>
@@ -98,7 +98,7 @@ coro_init (void)
abort ();
}
-# if CORO_SJLJ
+# if CORO_SJLJ || CORO_SJLJ_PTHREAD
static volatile int trampoline_done;
@@ -205,11 +205,15 @@ trampoline (int sig)
# endif
+#if CORO_SJLJ_PTHREAD
+#include <pthread.h>
+#endif
+
void
coro_create (coro_context *ctx, coro_func coro, void *arg, void *sptr, long ssize)
{
coro_context nctx;
-# if CORO_SJLJ
+# if CORO_SJLJ || CORO_SJLJ_PTHREAD
stack_t ostk, nstk;
struct sigaction osa, nsa;
sigset_t nsig, osig;
@@ -224,12 +228,16 @@ coro_create (coro_context *ctx, coro_func coro, void *arg, void *sptr, long ssiz
new_coro = ctx;
create_coro = &nctx;
-# if CORO_SJLJ
+# if CORO_SJLJ || CORO_SJLJ_PTHREAD
/* we use SIGUSR2. first block it, then fiddle with it. */
sigemptyset (&nsig);
sigaddset (&nsig, SIGUSR2);
+#if CORO_SJLJ
sigprocmask (SIG_BLOCK, &nsig, &osig);
+#else
+ pthread_sigmask (SIG_BLOCK, &nsig, &osig);
+#endif
nsa.sa_handler = trampoline;
sigemptyset (&nsa.sa_mask);
@@ -253,7 +261,11 @@ coro_create (coro_context *ctx, coro_func coro, void *arg, void *sptr, long ssiz
}
trampoline_done = 0;
+#if CORO_SJLJ
kill (getpid (), SIGUSR2);
+#else
+ pthread_kill (pthread_self(), SIGUSR2);
+#endif
sigfillset (&nsig); sigdelset (&nsig, SIGUSR2);
while (!trampoline_done)
@@ -272,7 +284,11 @@ coro_create (coro_context *ctx, coro_func coro, void *arg, void *sptr, long ssiz
sigaltstack (&ostk, 0);
sigaction (SIGUSR2, &osa, 0);
+#if CORO_SJLJ
sigprocmask (SIG_SETMASK, &osig, 0);
+#else
+ pthread_sigmask (SIG_SETMASK, &osig, 0);
+#endif
# elif CORO_LOSER
diff --git a/coro.h b/coro.h
index 52bb428..c5cf2a4 100644
--- a/coro.h
+++ b/coro.h
@@ -208,7 +208,7 @@ void coro_destroy (coro_context *ctx);
#if !defined(CORO_LOSER) && !defined(CORO_UCONTEXT) \
&& !defined(CORO_SJLJ) && !defined(CORO_LINUX) \
&& !defined(CORO_IRIX) && !defined(CORO_ASM) \
- && !defined(CORO_PTHREAD)
+ && !defined(CORO_PTHREAD) && !defined(CORO_SJLJ_PTHREAD)
# if defined(WINDOWS) || defined(_WIN32)
# define CORO_LOSER 1 /* you don't win with windoze */
# elif defined(__linux) && (defined(__x86) || defined (__amd64))
@@ -235,7 +235,7 @@ struct coro_context {
# define coro_transfer(p,n) swapcontext (&((p)->uc), &((n)->uc))
# define coro_destroy(ctx) (void *)(ctx)
-#elif CORO_SJLJ || CORO_LOSER || CORO_LINUX || CORO_IRIX
+#elif CORO_SJLJ || CORO_LOSER || CORO_LINUX || CORO_IRIX || CORO_SJLJ_PTHREAD
# if defined(CORO_LINUX) && !defined(_GNU_SOURCE)
# define _GNU_SOURCE /* for linux libc */