about summary refs log tree commit diff
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
parenta731e4103b87cb02b763f2e3f73cc43c72bdf65f (diff)
downloadmusl-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.
-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);