X-Git-Url: http://nsz.repo.hu/git/?p=musl;a=blobdiff_plain;f=src%2Fthread%2Fpthread_create.c;h=6c841be799b1632917c4b318dc0fa8faf4bd3e3a;hp=cf9cb191a52f80abbf43003fe253ea640d7cb232;hb=52d4444f8eec1a4e7e0861859c705c3a558b4e2a;hpb=082fb4e9bfd105fab3443c7b055bd9c22bdffcec diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index cf9cb191..6c841be7 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -30,13 +30,19 @@ _Noreturn void pthread_exit(void *result) /* Mark this thread dead before decrementing count */ __lock(self->killlock); self->dead = 1; - __unlock(self->killlock); /* Block all signals before decrementing the live thread count. * This is important to ensure that dynamically allocated TLS * is not under-allocated/over-committed, and possibly for other * reasons as well. */ - __syscall(SYS_rt_sigprocmask, SIG_BLOCK, SIGALL_SET, &set, _NSIG/8); + __block_all_sigs(&set); + + /* Wait to unlock the kill lock, which governs functions like + * pthread_kill which target a thread id, until signals have + * been blocked. This precludes observation of the thread id + * as a live thread (with application code running in it) after + * the thread was reported dead by ESRCH being returned. */ + __unlock(self->killlock); /* It's impossible to determine whether this is "the last thread" * until performing the atomic decrement, since multiple threads @@ -45,7 +51,7 @@ _Noreturn void pthread_exit(void *result) * stdio cleanup code a consistent state. */ if (a_fetch_add(&libc.threads_minus_1, -1)==0) { libc.threads_minus_1 = 0; - __syscall(SYS_rt_sigprocmask, SIG_SETMASK, &set, 0, _NSIG/8); + __restore_sigs(&set); exit(0); } @@ -88,8 +94,7 @@ static int start(void *p) self->detached = 2; pthread_exit(0); } - __syscall(SYS_rt_sigprocmask, SIG_SETMASK, - self->sigmask, 0, _NSIG/8); + __restore_sigs(self->sigmask); } if (self->unblock_cancel) __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, @@ -196,8 +201,7 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp } if (attr._a_sched) { do_sched = new->startlock[0] = 1; - __syscall(SYS_rt_sigprocmask, SIG_BLOCK, - SIGALL_SET, new->sigmask, _NSIG/8); + __block_app_sigs(new->sigmask); } new->unblock_cancel = self->cancel; new->canary = self->canary; @@ -208,8 +212,7 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp __release_ptc(); if (do_sched) { - __syscall(SYS_rt_sigprocmask, SIG_SETMASK, - new->sigmask, 0, _NSIG/8); + __restore_sigs(new->sigmask); } if (ret < 0) {