diff options
author | Rich Felker <dalias@aerifal.cx> | 2013-09-02 15:16:36 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2013-09-02 15:16:36 -0400 |
commit | 3c0501d28c1491ce9a4f675e9e223a8dfd9e134c (patch) | |
tree | fd32e20f204f9faef5bff8a33167f82b410f9cef | |
parent | a731e4103b87cb02b763f2e3f73cc43c72bdf65f (diff) | |
download | musl-3c0501d28c1491ce9a4f675e9e223a8dfd9e134c.tar.gz musl-3c0501d28c1491ce9a4f675e9e223a8dfd9e134c.tar.bz2 musl-3c0501d28c1491ce9a4f675e9e223a8dfd9e134c.tar.xz musl-3c0501d28c1491ce9a4f675e9e223a8dfd9e134c.zip |
in synccall, ignore the signal before any threads' signal handlers return
this protects against deadlock from spurious signals (e.g. sent by
another process) arriving after the controlling thread releases the
other threads from the sync operation.
-rw-r--r-- | src/thread/synccall.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/src/thread/synccall.c b/src/thread/synccall.c index c54570be..90ad1e25 100644 --- a/src/thread/synccall.c +++ b/src/thread/synccall.c @@ -71,6 +71,10 @@ void __synccall(void (*func)(void *), void *ctx) sigqueue(self->pid, SIGSYNCCALL, (union sigval){0}); while (sem_wait(&chaindone)); + sa.sa_flags = 0; + sa.sa_handler = SIG_IGN; + __libc_sigaction(SIGSYNCCALL, &sa, 0); + for (cur=head; cur; cur=cur->next) { sem_post(&cur->sem); while (sem_wait(&cur->sem2)); @@ -82,10 +86,6 @@ void __synccall(void (*func)(void *), void *ctx) sem_post(&cur->sem); } - sa.sa_flags = 0; - sa.sa_handler = SIG_IGN; - __libc_sigaction(SIGSYNCCALL, &sa, 0); - __syscall(SYS_rt_sigprocmask, SIG_SETMASK, &oldmask, 0, _NSIG/8); |