Skip to content

Commit ed6d133

Browse files
committed
Use tgkill() on Linux and FreeBSD
This eliminates the chance of rare bugs when thread IDs are recycled.
1 parent 97fc2aa commit ed6d133

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

libc/thread/pthread_kill.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "libc/intrin/atomic.h"
2525
#include "libc/intrin/describeflags.h"
2626
#include "libc/intrin/strace.h"
27+
#include "libc/runtime/internal.h"
2728
#include "libc/runtime/syslib.internal.h"
2829
#include "libc/sysv/consts/sicode.h"
2930
#include "libc/thread/posixthread.internal.h"
@@ -46,8 +47,12 @@ errno_t pthread_kill(pthread_t thread, int sig) {
4647
if (pt)
4748
_pthread_ref(pt);
4849
if (!thread) {
50+
// avoid crashing on easily predictable npe
51+
// chances are you need a barrier to synchronize startup
4952
err = EFAULT;
5053
} else if (!(1 <= sig && sig <= 64)) {
54+
// cosmo only supports this many signals
55+
// some platforms have more but we're not sure what they do
5156
err = EINVAL;
5257
} else if (thread == __get_tls()->tib_pthread) {
5358
err = raise(sig); // XNU will EDEADLK it otherwise
@@ -60,8 +65,15 @@ errno_t pthread_kill(pthread_t thread, int sig) {
6065
if (IsXnuSilicon()) {
6166
err = __syslib->__pthread_kill(_pthread_syshand(pt), sig);
6267
} else {
68+
int r = 0;
6369
int e = errno;
64-
if (sys_tkill(_pthread_tid(pt), sig, pt->tib)) {
70+
int tid = _pthread_tid(pt);
71+
if (IsLinux() || IsFreebsd()) {
72+
r = sys_tgkill(__pid, tid, sig);
73+
} else {
74+
r = sys_tkill(tid, sig, pt->tib);
75+
}
76+
if (r) {
6577
err = errno;
6678
errno = e;
6779
}

0 commit comments

Comments
 (0)