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 /src | |
parent | a731e4103b87cb02b763f2e3f73cc43c72bdf65f (diff) | |
download | musl-3c0501d28c1491ce9a4f675e9e223a8dfd9e134c.tar.gz 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.
Diffstat (limited to 'src')
-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); |