diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-11-15 21:37:06 -0700 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-11-19 20:15:48 -0700 |
commit | 712f71f1a7c6d06ce9f8f011c5d5c03add0e9d72 (patch) | |
tree | 8e3bab659161d6f98cb9088f5493bfcc55c7617f /libcr/coroutine.c | |
parent | 51e4ec63b745836c33b6f92c9cbfafb8892e1843 (diff) |
libcr: Fix races?
Diffstat (limited to 'libcr/coroutine.c')
-rw-r--r-- | libcr/coroutine.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/libcr/coroutine.c b/libcr/coroutine.c index 9f1150b..6549070 100644 --- a/libcr/coroutine.c +++ b/libcr/coroutine.c @@ -156,13 +156,16 @@ * Interrupt management routines. */ #if __unix__ #include <signal.h> /* for sig*, SIG_* */ - #include <unistd.h> /* for pause() */ - static inline void cr_plat_wait_for_interrupt(void) { - pause(); - } /* For a signal to be *in* the mask means that the signal is * *blocked*. */ + static inline void cr_plat_wait_for_interrupt(void) { + sigset_t set; + sigemptyset(&set); + sigsuspend(&set); + sigfillset(&set); + sigprocmask(SIG_SETMASK, &set, NULL); + } void _cr_plat_disable_interrupts(void) { sigset_t all; sigfillset(&all); @@ -490,9 +493,7 @@ void coroutine_main(void) { while ( !((next = coroutine_ringbuf_pop())) ) { /* No coroutines are runnable, wait for an interrupt * to change that. */ - cr_enable_interrupts(); cr_plat_wait_for_interrupt(); - cr_disable_interrupts(); } if (!cr_plat_setjmp(coroutine_main_env)) { /* point=b */ @@ -530,9 +531,7 @@ static inline void _cr_yield() { while ( !((next = coroutine_ringbuf_pop())) ) { /* No coroutines are runnable, wait for an interrupt * to change that. */ - cr_enable_interrupts(); cr_plat_wait_for_interrupt(); - cr_disable_interrupts(); } if (next == coroutine_running) { |