summaryrefslogtreecommitdiff
path: root/libcr/coroutine.c
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2024-11-15 21:37:06 -0700
committerLuke T. Shumaker <lukeshu@lukeshu.com>2024-11-19 20:15:48 -0700
commit712f71f1a7c6d06ce9f8f011c5d5c03add0e9d72 (patch)
tree8e3bab659161d6f98cb9088f5493bfcc55c7617f /libcr/coroutine.c
parent51e4ec63b745836c33b6f92c9cbfafb8892e1843 (diff)
libcr: Fix races?
Diffstat (limited to 'libcr/coroutine.c')
-rw-r--r--libcr/coroutine.c15
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) {