summaryrefslogtreecommitdiff
path: root/src/thread/pthread_kill.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2018-05-04 14:26:31 -0400
committerRich Felker <dalias@aerifal.cx>2018-05-05 11:09:51 -0400
commit526e64f54d729947b35fd39129bc86cbc0b5f098 (patch)
treed13eff2e89069dadfff5ea537c56f422847f8def /src/thread/pthread_kill.c
parent4df42163511182bfd6fc55e85250b93786dcce7e (diff)
downloadmusl-526e64f54d729947b35fd39129bc86cbc0b5f098.tar.gz
improve pthread_exit synchronization with functions targeting tid
if the last thread exited via pthread_exit, the logic that marked it dead did not account for the possibility of it targeting itself via atexit handlers. for example, an atexit handler calling pthread_kill(pthread_self(), SIGKILL) would return success (previously, ESRCH) rather than causing termination via the signal. move the release of killlock after the determination is made whether the exiting thread is the last thread. in the case where it's not, move the release all the way to the end of the function. this way we can clear the tid rather than spending storage on a dedicated dead-flag. clearing the tid is also preferable in that it hardens against inadvertent use of the value after the thread has terminated but before it is joined.
Diffstat (limited to 'src/thread/pthread_kill.c')
-rw-r--r--src/thread/pthread_kill.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/src/thread/pthread_kill.c b/src/thread/pthread_kill.c
index 0a139231..6d70e626 100644
--- a/src/thread/pthread_kill.c
+++ b/src/thread/pthread_kill.c
@@ -4,8 +4,8 @@ int pthread_kill(pthread_t t, int sig)
{
int r;
LOCK(t->killlock);
- r = t->dead ? (sig+0U >= _NSIG ? EINVAL : 0)
- : -__syscall(SYS_tkill, t->tid, sig);
+ r = t->tid ? -__syscall(SYS_tkill, t->tid, sig)
+ : (sig+0U >= _NSIG ? EINVAL : 0);
UNLOCK(t->killlock);
return r;
}