summaryrefslogtreecommitdiff
path: root/src/thread/pthread_kill.c
AgeCommit message (Collapse)AuthorLines
2020-07-06fix async-cancel-safety of pthread_cancelRich Felker-1/+4
the previous commit addressing async-signal-safety issues around pthread_kill did not fully fix pthread_cancel, which is also required (albeit rather irrationally) to be async-cancel-safe. without blocking implementation-internal signals, it's possible that, when async cancellation is enabled, a cancel signal sent by another thread interrupts pthread_kill while the killlock for a targeted thread is held. as a result, the calling thread will terminate due to cancellation without ever unlocking the targeted thread's killlock, and thus the targeted thread will be unable to exit.
2020-07-06make thread killlock async-signal-safe for pthread_killRich Felker-0/+3
pthread_kill is required to be AS-safe. that requirement can't be met if the target thread's killlock can be taken in contexts where application-installed signal handlers can run. block signals around use of this lock in all pthread_* functions which target a tid, and reorder blocking/unblocking of signals in pthread_exit so that they're blocked whenever the killlock is held.
2018-09-12split internal lock API out of libc.h, creating lock.hRich Felker-0/+1
this further reduces the number of source files which need to include libc.h and thereby be potentially exposed to libc global state and internals. this will also facilitate further improvements like adding an inline fast-path, if we want to do so later.
2018-05-05improve pthread_exit synchronization with functions targeting tidRich Felker-2/+2
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.
2018-05-04remove incorrect ESRCH error from pthread_killRich Felker-1/+2
posix documents in the rationale and future directions for pthread_kill that, since the lifetime of the thread id for a joinable thread lasts until it is joined, ESRCH is not a correct error for pthread_kill to produce when the target thread has exited but not yet been joined, and that conforming applications cannot attempt to detect this state. future versions of the standard may explicitly require that ESRCH not be returned for this case.
2018-01-09consistently use the LOCK an UNLOCK macrosJens Gustedt-2/+2
In some places there has been a direct usage of the functions. Use the macros consistently everywhere, such that it might be easier later on to capture the fast path directly inside the macro and only have the call overhead on the slow path.
2014-07-05eliminate use of cached pid from thread structureRich Felker-1/+1
the main motivation for this change is to remove the assumption that the tid of the main thread is also the pid of the process. (the value returned by the set_tid_address syscall was used to fill both fields despite it semantically being the tid.) this is historically and presently true on linux and unlikely to change, but it conceivably could be false on other systems that otherwise reproduce the linux syscall api/abi. only a few parts of the code were actually still using the cached pid. in a couple places (aio and synccall) it was a minor optimization to avoid a syscall. caching could be reintroduced, but lazily as part of the public getpid function rather than at program startup, if it's deemed important for performance later. in other places (cancellation and pthread_kill) the pid was completely unnecessary; the tkill syscall can be used instead of tgkill. this is actually a rather subtle issue, since tgkill is supposedly a solution to race conditions that can affect use of tkill. however, as documented in the commit message for commit 7779dbd2663269b465951189b4f43e70839bc073, tgkill does not actually solve this race; it just limits it to happening within one process rather than between processes. we use a lock that avoids the race in pthread_kill, and the use in the cancellation signal handler is self-targeted and thus not subject to tid reuse races, so both are safe regardless of which syscall (tgkill or tkill) is used.
2012-07-12fix several locks that weren't updated right for new futex-based __lockRich Felker-2/+2
these could have caused memory corruption due to invalid accesses to the next field. all should be fixed now; I found the errors with fgrep -r '__lock(&', which is bogus since the argument should be an array.
2012-07-12fix pthread_kill unlockingRich Felker-1/+1
it had not been updated for the futex-based locks
2011-06-14fix race condition in pthread_killRich Felker-1/+5
if thread id was reused by the kernel between the time pthread_kill read it from the userspace pthread_t object and the time of the tgkill syscall, a signal could be sent to the wrong thread. the tgkill syscall was supposed to prevent this race (versus the old tkill syscall) but it can't; it can only help in the case where the tid is reused in a different process, but not when the tid is reused in the same process. the only solution i can see is an extra lock to prevent threads from exiting while another thread is trying to pthread_kill them. it should be very very cheap in the non-contended case.
2011-04-06consistency: change all remaining syscalls to use SYS_ rather than __NR_ prefixRich Felker-1/+1
2011-03-19if returning errno value directly from a syscall, we need to negate it.Rich Felker-1/+1
2011-03-19syscall overhaul part two - unify public and internal syscall interfaceRich Felker-2/+1
with this patch, the syscallN() functions are no longer needed; a variadic syscall() macro allows syscalls with anywhere from 0 to 6 arguments to be made with a single macro name. also, manually casting each non-integer argument with (long) is no longer necessary; the casts are hidden in the macros. some source files which depended on being able to define the old macro SYSCALL_RETURNS_ERRNO have been modified to directly use __syscall() instead of syscall(). references to SYSCALL_SIGSET_SIZE and SYSCALL_LL have also been changed. x86_64 has not been tested, and may need a follow-up commit to fix any minor bugs/oversights.
2011-02-12initial check-in, version 0.5.0v0.5.0Rich Felker-0/+7