summaryrefslogtreecommitdiff
path: root/coro.c
diff options
context:
space:
mode:
Diffstat (limited to 'coro.c')
-rw-r--r--coro.c26
1 files changed, 21 insertions, 5 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