mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Use tgkill() on Linux and FreeBSD
This eliminates the chance of rare bugs when thread IDs are recycled.
This commit is contained in:
parent
97fc2aab41
commit
ed6d133a27
1 changed files with 13 additions and 1 deletions
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue