summaryrefslogtreecommitdiff
path: root/src/thread/synccall.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2013-09-02 15:16:36 -0400
committerRich Felker <dalias@aerifal.cx>2013-09-02 15:16:36 -0400
commit3c0501d28c1491ce9a4f675e9e223a8dfd9e134c (patch)
treefd32e20f204f9faef5bff8a33167f82b410f9cef /src/thread/synccall.c
parenta731e4103b87cb02b763f2e3f73cc43c72bdf65f (diff)
downloadmusl-3c0501d28c1491ce9a4f675e9e223a8dfd9e134c.tar.gz
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/thread/synccall.c')
-rw-r--r--src/thread/synccall.c8
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);