in synccall, ignore the signal before any threads' signal handlers return
authorRich Felker <dalias@aerifal.cx>
Mon, 2 Sep 2013 19:16:36 +0000 (15:16 -0400)
committerRich Felker <dalias@aerifal.cx>
Mon, 2 Sep 2013 19:16:36 +0000 (15:16 -0400)
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.

src/thread/synccall.c

index c54570befc05ec95d0083d51428735e441ace6ba..90ad1e25795888851dd3acc661d4f90798203363 100644 (file)
@@ -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);