Skip to content

Commit

Permalink
Use tgkill() on Linux and FreeBSD
Browse files Browse the repository at this point in the history
This eliminates the chance of rare bugs when thread IDs are recycled.
  • Loading branch information
jart committed Jan 4, 2025
1 parent 97fc2aa commit ed6d133
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion libc/thread/pthread_kill.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "libc/intrin/atomic.h"
#include "libc/intrin/describeflags.h"
#include "libc/intrin/strace.h"
#include "libc/runtime/internal.h"
#include "libc/runtime/syslib.internal.h"
#include "libc/sysv/consts/sicode.h"
#include "libc/thread/posixthread.internal.h"
Expand All @@ -46,8 +47,12 @@ errno_t pthread_kill(pthread_t thread, int sig) {
if (pt)
_pthread_ref(pt);
if (!thread) {
// avoid crashing on easily predictable npe
// chances are you need a barrier to synchronize startup
err = EFAULT;
} else if (!(1 <= sig && sig <= 64)) {
// cosmo only supports this many signals
// some platforms have more but we're not sure what they do
err = EINVAL;
} else if (thread == __get_tls()->tib_pthread) {
err = raise(sig); // XNU will EDEADLK it otherwise
Expand All @@ -60,8 +65,15 @@ errno_t pthread_kill(pthread_t thread, int sig) {
if (IsXnuSilicon()) {
err = __syslib->__pthread_kill(_pthread_syshand(pt), sig);
} else {
int r = 0;
int e = errno;
if (sys_tkill(_pthread_tid(pt), sig, pt->tib)) {
int tid = _pthread_tid(pt);
if (IsLinux() || IsFreebsd()) {
r = sys_tgkill(__pid, tid, sig);
} else {
r = sys_tkill(tid, sig, pt->tib);
}
if (r) {
err = errno;
errno = e;
}
Expand Down

0 comments on commit ed6d133

Please sign in to comment.