diff --git a/libc/calls/__sig2.c b/libc/calls/__sig2.c index 0b2d2f97e..8c60686f6 100644 --- a/libc/calls/__sig2.c +++ b/libc/calls/__sig2.c @@ -17,44 +17,35 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "ape/sections.internal.h" -#include "libc/assert.h" -#include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/sig.internal.h" #include "libc/calls/state.internal.h" #include "libc/calls/struct/sigaction.h" #include "libc/calls/struct/siginfo.h" -#include "libc/calls/struct/sigset.h" #include "libc/calls/struct/ucontext.internal.h" -#include "libc/calls/ucontext.h" #include "libc/intrin/describebacktrace.internal.h" #include "libc/intrin/strace.internal.h" -#include "libc/intrin/weaken.h" #include "libc/log/libfatal.internal.h" -#include "libc/macros.internal.h" -#include "libc/nexgen32e/stackframe.h" #include "libc/nt/console.h" #include "libc/nt/enum/context.h" -#include "libc/nt/runtime.h" #include "libc/nt/struct/context.h" #include "libc/nt/thread.h" -#include "libc/runtime/internal.h" -#include "libc/runtime/runtime.h" #include "libc/str/str.h" #include "libc/sysv/consts/sa.h" +#include "libc/sysv/consts/sicode.h" #include "libc/sysv/consts/sig.h" -#include "libc/sysv/errfuns.h" #include "libc/thread/tls.h" #ifdef __x86_64__ /** - * Returns true if signal default action is to end process. + * Returns true if signal is ignored by default. */ -textwindows bool __sig_is_fatal(int sig) { - return !(sig == SIGURG || // - sig == SIGCHLD || // - sig == SIGWINCH); +textwindows bool __sig_is_ignored(int sig) { + return sig == SIGURG || // + sig == SIGCONT || // + sig == SIGCHLD || // + sig == SIGWINCH; } /** @@ -70,70 +61,14 @@ textwindows bool __sig_is_core(int sig) { sig == SIGXFSZ; } -/** - * Allocates piece of memory for storing pending signal. - * @assume lock is held - */ -static textwindows struct Signal *__sig_alloc(void) { - int i; - struct Signal *res = 0; - for (i = 0; i < ARRAYLEN(__sig.mem); ++i) { - if (!__sig.mem[i].used) { - __sig.mem[i].used = true; - res = __sig.mem + i; - break; - } - } - return res; -} - -/** - * Returns signal memory to static pool. - */ -static textwindows void __sig_free(struct Signal *mem) { - mem->used = false; -} - static inline textwindows int __sig_is_masked(int sig) { if (__tls_enabled) { return __get_tls()->tib_sigmask & (1ull << (sig - 1)); } else { - return __sig.sigmask & (1ull << (sig - 1)); + return __sig.mask & (1ull << (sig - 1)); } } -textwindows int __sig_is_applicable(struct Signal *s) { - return s->tid <= 0 || s->tid == gettid(); -} - -/** - * Dequeues signal that isn't masked. - * @return signal or null if empty or none unmasked - */ -static textwindows struct Signal *__sig_remove(int sigops) { - struct Signal *prev, *res; - if (__sig.queue) { - __sig_lock(); - for (prev = 0, res = __sig.queue; res; prev = res, res = res->next) { - if (__sig_is_applicable(res) && // - !__sig_is_masked(res->sig) && // - !((sigops & kSigOpNochld) && res->sig == SIGCHLD)) { - if (res == __sig.queue) { - __sig.queue = res->next; - } else if (prev) { - prev->next = res->next; - } - res->next = 0; - break; - } - } - __sig_unlock(); - } else { - res = 0; - } - return res; -} - /** * Delivers signal to callback. * @@ -168,7 +103,7 @@ bool __sig_deliver(int sigops, int sig, int sic, ucontext_t *ctx) { if (__tls_enabled) { oldmask = __get_tls()->tib_sigmask; } else { - oldmask = __sig.sigmask; + oldmask = __sig.mask; } if (ctx) { ctx->uc_sigmask = (sigset_t){{oldmask}}; @@ -179,7 +114,7 @@ bool __sig_deliver(int sigops, int sig, int sic, ucontext_t *ctx) { if (__tls_enabled) { __get_tls()->tib_sigmask |= 1ull << (sig - 1); } else { - __sig.sigmask |= 1ull << (sig - 1); + __sig.mask |= 1ull << (sig - 1); } } @@ -192,7 +127,7 @@ bool __sig_deliver(int sigops, int sig, int sic, ucontext_t *ctx) { if (__tls_enabled) { __get_tls()->tib_sigmask = oldmask; } else { - __sig.sigmask = oldmask; + __sig.mask = oldmask; } if (flags & SA_RESETHAND) { __sighandrvas[sig] = (int32_t)(intptr_t)SIG_DFL; @@ -213,17 +148,25 @@ bool __sig_deliver(int sigops, int sig, int sic, ucontext_t *ctx) { * @return true if `EINTR` should be raised */ textwindows bool __sig_handle(int sigops, int sig, int sic, ucontext_t *ctx) { + if (__sighandrvas[sig] == (intptr_t)SIG_IGN || + (__sighandrvas[sig] == (intptr_t)SIG_DFL && __sig_is_ignored(sig))) { + return false; + } if (__sig_is_masked(sig)) { if (sigops & kSigOpUnmaskable) { goto DefaultAction; } - __sig_add(0, sig, sic); + if (__tls_enabled) { + __get_tls()->tib_sigpending |= 1ull << (sig - 1); + } else { + __sig.pending |= 1ull << (sig - 1); + } return false; } switch (__sighandrvas[sig]) { case (intptr_t)SIG_DFL: DefaultAction: - if (__sig_is_fatal(sig)) { + if (!__sig_is_ignored(sig)) { uint32_t cmode; intptr_t hStderr; const char *signame; @@ -254,40 +197,15 @@ textwindows bool __sig_handle(int sigops, int sig, int sic, ucontext_t *ctx) { } } -/** - * Enqueues generic signal for delivery on New Technology. - * @return 0 on success, otherwise -1 w/ errno - * @threadsafe - */ -textwindows int __sig_add(int tid, int sig, int si_code) { - int rc; - struct Signal *mem; - if (1 <= sig && sig <= 64) { - if (__sighandrvas[sig] == (unsigned)(uintptr_t)SIG_IGN || - (__sighandrvas[sig] == (unsigned)(uintptr_t)SIG_DFL && - !__sig_is_fatal(sig))) { - STRACE("ignoring %G", sig); - rc = 0; - } else { - STRACE("enqueuing %G", sig); - __sig_lock(); - ++__sig_count; - if ((mem = __sig_alloc())) { - mem->tid = tid; - mem->sig = sig; - mem->si_code = si_code; - mem->next = __sig.queue; - __sig.queue = mem; - rc = 0; - } else { - rc = enomem(); - } - __sig_unlock(); +static textwindows bool __sig_checkem(int sigops, uint64_t *pending) { + bool res = false; + for (int sig = 1; sig <= 64; ++sig) { + if (*pending & (1ull << (sig - 1))) { + *pending &= ~(1ull << (sig - 1)); + res |= __sig_handle(sigops, sig, SI_KERNEL, 0); } - } else { - rc = einval(); } - return rc; + return res; } /** @@ -297,49 +215,11 @@ textwindows int __sig_add(int tid, int sig, int si_code) { * @threadsafe */ textwindows bool __sig_check(int sigops) { - bool delivered; - struct Signal *sig; - delivered = false; - while ((sig = __sig_remove(sigops))) { - delivered |= __sig_handle(sigops, sig->sig, sig->si_code, 0); - __sig_free(sig); - } - return delivered; -} - -/** - * Determines if a signal should be ignored and if so discards existing - * instances of said signal on New Technology. - * - * Even blocked signals are discarded. - * - * @param sig the signal number to remove - * @threadsafe - */ -textwindows void __sig_check_ignore(const int sig, const unsigned rva) { - struct Signal *cur, *prev, *next; - if (rva != (unsigned)(intptr_t)SIG_IGN && - (rva != (unsigned)(intptr_t)SIG_DFL || __sig_is_fatal(sig))) { - return; - } - if (__sig.queue) { - __sig_lock(); - for (prev = 0, cur = __sig.queue; cur; cur = next) { - next = cur->next; - if (sig == cur->sig) { - if (cur == __sig.queue) { - __sig.queue = cur->next; - } else if (prev) { - prev->next = cur->next; - } - __sig_handle(0, cur->sig, cur->si_code, 0); - __sig_free(cur); - } else { - prev = cur; - } - } - __sig_unlock(); + bool res = false; + if (__tls_enabled) { + res |= __sig_checkem(sigops, &__get_tls()->tib_sigpending); } + return res | __sig_checkem(sigops, &__sig.pending); } #endif /* __x86_64__ */ diff --git a/libc/calls/__sig_mask.c b/libc/calls/__sig_mask.c index 35fa15b68..f4fbbc53b 100644 --- a/libc/calls/__sig_mask.c +++ b/libc/calls/__sig_mask.c @@ -33,7 +33,7 @@ textwindows int __sig_mask(int how, const sigset_t *neu, sigset_t *old) { if (__tls_enabled) { mask = &__get_tls()->tib_sigmask; } else { - mask = &__sig.sigmask; + mask = &__sig.mask; } if (old) { old->__bits[0] = *mask; diff --git a/libc/calls/__sig_pending.c b/libc/calls/__sig_pending.c deleted file mode 100644 index f654ff18a..000000000 --- a/libc/calls/__sig_pending.c +++ /dev/null @@ -1,47 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2022 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/calls.h" -#include "libc/calls/sig.internal.h" -#include "libc/calls/state.internal.h" -#include "libc/calls/struct/sigset.h" - -#ifdef __x86_64__ - -/** - * Determines the pending signals on New Technology. - * - * @param pending is to hold the pending signals - * @threadsafe - */ -textwindows void __sig_pending(sigset_t *pending) { - struct Signal *s; - sigemptyset(pending); - if (__sig.queue) { - __sig_lock(); - for (s = __sig.queue; s; s = s->next) { - if (__sig_is_applicable(s) && - __sighandrvas[s->sig] != (unsigned)(intptr_t)SIG_IGN) { - sigaddset(pending, s->sig); - } - } - __sig_unlock(); - } -} - -#endif /* __x86_64__ */ diff --git a/libc/calls/getrusage-nt.c b/libc/calls/getrusage-nt.c index 08bedde7e..47ba7fe1e 100644 --- a/libc/calls/getrusage-nt.c +++ b/libc/calls/getrusage-nt.c @@ -53,7 +53,7 @@ textwindows int sys_getrusage_nt(int who, struct rusage *usage) { .ru_majflt = memcount.PageFaultCount, .ru_inblock = iocount.ReadOperationCount, .ru_oublock = iocount.WriteOperationCount, - .ru_nsignals = __sig_count, + .ru_nsignals = __sig.count, }; return 0; } diff --git a/libc/calls/onntconsoleevent.c b/libc/calls/onntconsoleevent.c index 992102b6b..4b14089fd 100644 --- a/libc/calls/onntconsoleevent.c +++ b/libc/calls/onntconsoleevent.c @@ -45,7 +45,7 @@ static textwindows int GetSig(uint32_t dwCtrlType) { case kNtCtrlShutdownEvent: // only received by services return SIGHUP; default: - __builtin_unreachable(); + return SIGSTKFLT; } } @@ -60,7 +60,7 @@ textwindows bool32 __sig_notify(int sig, int sic) { // if we don't have tls, then we can't hijack a safe stack from a // thread so just try our luck punting the signal to the next i/o if (!__tls_enabled) { - __sig_add(0, sig, sic); + __sig.pending |= 1ull << (sig - 1); return true; } @@ -79,7 +79,7 @@ textwindows bool32 __sig_notify(int sig, int sic) { if (pt->tib->tib_sigmask & (1ull << (sig - 1))) continue; // masked if (pt->flags & PT_BLOCKED) { pthread_spin_unlock(&_pthread_lock); - __sig_add(0, sig, sic); + __sig.pending |= 1ull << (sig - 1); return true; } } @@ -98,9 +98,7 @@ textwindows bool32 __sig_notify(int sig, int sic) { if (tid <= 0) continue; // -1 means spawning, 0 means terminated if (pt->tib->tib_sigmask & (1ull << (sig - 1))) continue; // masked pthread_spin_unlock(&_pthread_lock); - if (_pthread_signal(pt, sig, sic) == -1) { - __sig_add(0, sig, sic); - } + _pthread_signal(pt, sig, sic); return true; } @@ -109,7 +107,8 @@ textwindows bool32 __sig_notify(int sig, int sic) { } __msabi textwindows bool32 __onntconsoleevent(uint32_t dwCtrlType) { - return __sig_notify(GetSig(dwCtrlType), SI_KERNEL); + __sig_notify(GetSig(dwCtrlType), SI_KERNEL); + return true; } #endif /* __x86_64__ */ diff --git a/libc/calls/setitimer-nt.c b/libc/calls/setitimer-nt.c index 474d16211..2eae3e706 100644 --- a/libc/calls/setitimer-nt.c +++ b/libc/calls/setitimer-nt.c @@ -40,7 +40,7 @@ textwindows void _check_sigalrm(void) { timeval_add(g_setitimer.it_value, g_setitimer.it_interval); } while (timeval_cmp(now, g_setitimer.it_value) > 0); } - __sig_add(0, SIGALRM, SI_TIMER); + __sig.pending |= 1ull << (SIGALRM - 1); } textwindows void sys_setitimer_nt_reset(void) { diff --git a/libc/calls/sig.internal.h b/libc/calls/sig.internal.h index 77c017988..582b008ce 100644 --- a/libc/calls/sig.internal.h +++ b/libc/calls/sig.internal.h @@ -1,6 +1,5 @@ #ifndef COSMOPOLITAN_LIBC_CALLS_SIGNALS_INTERNAL_H_ #define COSMOPOLITAN_LIBC_CALLS_SIGNALS_INTERNAL_H_ -#include "libc/atomic.h" #include "libc/calls/struct/sigset.h" #include "libc/calls/ucontext.h" #include "libc/nt/struct/context.h" @@ -19,32 +18,19 @@ struct Delivery { struct NtContext *nc; }; -struct Signal { - struct Signal *next; - bool used; - int tid; - int sig; - int si_code; -}; - struct Signals { - uint64_t sigmask; /* only if tls is disabled */ - struct Signal *queue; - struct Signal mem[__SIG_QUEUE_LENGTH]; + uint64_t mask; + uint64_t pending; + uint64_t count; }; extern struct Signals __sig; -extern atomic_long __sig_count; bool __sig_check(int); bool __sig_is_core(int); -bool __sig_is_fatal(int); +bool __sig_is_ignored(int); bool __sig_handle(int, int, int, ucontext_t *); -int __sig_add(int, int, int); int __sig_mask(int, const sigset_t *, sigset_t *); -void __sig_check_ignore(const int, const unsigned); -void __sig_pending(sigset_t *); -int __sig_is_applicable(struct Signal *); bool __sig_deliver(int, int, int, ucontext_t *); int __sig_tramp(struct Delivery *); bool32 __sig_notify(int, int); diff --git a/libc/calls/sigaction.c b/libc/calls/sigaction.c index f83af9577..a6bd1dff6 100644 --- a/libc/calls/sigaction.c +++ b/libc/calls/sigaction.c @@ -47,6 +47,7 @@ #include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/sig.h" #include "libc/sysv/errfuns.h" +#include "libc/thread/tls.h" #ifdef SYSDEBUG __static_yoink("strsignal"); // for kprintf() @@ -264,7 +265,13 @@ static int __sigaction(int sig, const struct sigaction *act, __sighandrvas[sig] = rva; __sighandflags[sig] = act->sa_flags; if (IsWindows()) { - __sig_check_ignore(sig, rva); + if (rva == (intptr_t)SIG_IGN || + (rva == (intptr_t)SIG_DFL && __sig_is_ignored(sig))) { + __sig.pending &= ~(1ull << (sig - 1)); + if (__tls_enabled) { + __get_tls()->tib_sigpending &= ~(1ull << (sig - 1)); + } + } } } } diff --git a/libc/calls/sigcount.c b/libc/calls/sigcount.c deleted file mode 100644 index f26517129..000000000 --- a/libc/calls/sigcount.c +++ /dev/null @@ -1,21 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2022 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/sig.internal.h" - -atomic_long __sig_count; diff --git a/libc/calls/siglock.c b/libc/calls/siglock.c deleted file mode 100644 index b023ecb02..000000000 --- a/libc/calls/siglock.c +++ /dev/null @@ -1,38 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2022 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/state.internal.h" -#include "libc/str/str.h" -#include "libc/thread/thread.h" - -void(__sig_lock)(void) { - pthread_mutex_lock(&__sig_lock_obj); -} - -void(__sig_unlock)(void) { - pthread_mutex_unlock(&__sig_lock_obj); -} - -void __sig_funlock(void) { - bzero(&__sig_lock_obj, sizeof(__sig_lock_obj)); - __sig_lock_obj._type = PTHREAD_MUTEX_RECURSIVE; -} - -__attribute__((__constructor__)) static void __sig_init(void) { - pthread_atfork(__sig_lock, __sig_unlock, __sig_funlock); -} diff --git a/libc/calls/siglock_obj.c b/libc/calls/siglock_obj.c deleted file mode 100644 index 8e70e819d..000000000 --- a/libc/calls/siglock_obj.c +++ /dev/null @@ -1,22 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2022 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/state.internal.h" -#include "libc/thread/thread.h" - -pthread_mutex_t __sig_lock_obj; diff --git a/libc/calls/sigpending.c b/libc/calls/sigpending.c index edbf505a6..57198dabf 100644 --- a/libc/calls/sigpending.c +++ b/libc/calls/sigpending.c @@ -24,6 +24,7 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/strace.internal.h" #include "libc/sysv/errfuns.h" +#include "libc/thread/tls.h" /** * Determines the blocked pending signals @@ -57,8 +58,7 @@ int sigpending(sigset_t *pending) { } } } else if (IsWindows()) { - sigemptyset(pending); - __sig_pending(pending); + *pending = (sigset_t){{__sig.pending | __get_tls()->tib_sigpending}}; rc = 0; } else { rc = enosys(); diff --git a/libc/calls/state.internal.h b/libc/calls/state.internal.h index 878de9e4a..054ea5bfe 100644 --- a/libc/calls/state.internal.h +++ b/libc/calls/state.internal.h @@ -8,7 +8,6 @@ COSMOPOLITAN_C_START_ extern int __vforked; extern bool __time_critical; extern pthread_mutex_t __fds_lock_obj; -extern pthread_mutex_t __sig_lock_obj; extern unsigned __sighandrvas[NSIG + 1]; extern unsigned __sighandflags[NSIG + 1]; extern const struct NtSecurityAttributes kNtIsInheritable; @@ -16,9 +15,6 @@ extern const struct NtSecurityAttributes kNtIsInheritable; void __fds_lock(void); void __fds_unlock(void); void __fds_funlock(void); -void __sig_lock(void); -void __sig_unlock(void); -void __sig_funlock(void); #define __vforked (__tls_enabled && (__get_tls()->tib_flags & TIB_FLAG_VFORKED)) diff --git a/libc/calls/tkill.c b/libc/calls/tkill.c index 2d4fa2cfd..ff6d4df0a 100644 --- a/libc/calls/tkill.c +++ b/libc/calls/tkill.c @@ -49,11 +49,8 @@ static dontinline textwindows int __tkill_nt(int tid, int sig, } // check if caller is killing themself - if (tid == gettid() && __tls_enabled && (!tib || tib == __get_tls())) { - struct NtContext nc = {.ContextFlags = kNtContextAll}; - struct Delivery pkg = {0, sig, SI_TKILL, &nc}; - unassert(GetThreadContext(GetCurrentThread(), &nc)); - __sig_tramp(&pkg); + if (tid == gettid() && (!tib || tib == __get_tls())) { + __sig_handle(0, sig, SI_TKILL, 0); return 0; } @@ -70,7 +67,8 @@ static dontinline textwindows int __tkill_nt(int tid, int sig, pthread_spin_unlock(&_pthread_lock); if (status < kPosixThreadTerminated) { if (pt->flags & PT_BLOCKED) { - return __sig_add(tid, sig, SI_TKILL); + pt->tib->tib_sigpending |= 1ull << (sig - 1); + return 0; } else { return _pthread_signal(pt, sig, SI_TKILL); } diff --git a/libc/calls/wincrash.c b/libc/calls/wincrash.c index 9f1036e46..3ae800eab 100644 --- a/libc/calls/wincrash.c +++ b/libc/calls/wincrash.c @@ -24,6 +24,7 @@ #include "libc/nt/enum/exceptionhandleractions.h" #include "libc/nt/enum/signal.h" #include "libc/nt/enum/status.h" +#include "libc/nt/runtime.h" #include "libc/nt/struct/ntexceptionpointers.h" #include "libc/nt/thunk/msabi.h" #include "libc/sysv/consts/sa.h" diff --git a/libc/calls/__sig.c b/libc/intrin/sig.c similarity index 96% rename from libc/calls/__sig.c rename to libc/intrin/sig.c index d6d08d476..f8bf74a1c 100644 --- a/libc/calls/__sig.c +++ b/libc/intrin/sig.c @@ -1,7 +1,7 @@ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ │vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2022 Justine Alexandra Roberts Tunney │ +│ Copyright 2023 Justine Alexandra Roberts Tunney │ │ │ │ Permission to use, copy, modify, and/or distribute this software for │ │ any purpose with or without fee is hereby granted, provided that the │ diff --git a/libc/thread/tls.h b/libc/thread/tls.h index 07a152b8b..4541e8ad2 100644 --- a/libc/thread/tls.h +++ b/libc/thread/tls.h @@ -27,10 +27,10 @@ struct CosmoTib { _Atomic(int32_t) tib_tid; /* 0x38 transitions -1 → tid → 0 */ int32_t tib_errno; /* 0x3c */ uint64_t tib_flags; /* 0x40 */ - long __padding; - int tib_ftrace; /* inherited */ - int tib_strace; /* inherited */ - uint64_t tib_sigmask; /* inherited */ + int tib_ftrace; /* inherited */ + int tib_strace; /* inherited */ + uint64_t tib_sigmask; /* inherited */ + uint64_t tib_sigpending; void *tib_reserved4; void *tib_reserved5; void *tib_reserved6; diff --git a/test/libc/calls/sigaction_test.c b/test/libc/calls/sigaction_test.c index 4e01b02f4..2320f28d2 100644 --- a/test/libc/calls/sigaction_test.c +++ b/test/libc/calls/sigaction_test.c @@ -273,9 +273,6 @@ sig_atomic_t gotusr1; void OnSigMask(int sig, struct siginfo *si, void *ctx) { ucontext_t *uc = ctx; -#ifdef __x86_64__ - ASSERT_EQ(123, uc->uc_mcontext.r15); -#endif sigaddset(&uc->uc_sigmask, sig); gotusr1 = true; } @@ -288,9 +285,6 @@ TEST(uc_sigmask, signalHandlerCanChangeSignalMaskOfTrappedThread) { ASSERT_SYS(0, 0, sigprocmask(SIG_SETMASK, &want, &got)); ASSERT_FALSE(sigismember(&got, SIGUSR1)); ASSERT_SYS(0, 0, sigaction(SIGUSR1, &sa, &oldsa)); -#ifdef __x86_64__ - asm volatile("mov\t%0,%%r15" : : "i"(123) : "r15", "memory"); -#endif ASSERT_SYS(0, 0, raise(SIGUSR1)); ASSERT_TRUE(gotusr1); ASSERT_SYS(0, 0, sigprocmask(SIG_SETMASK, 0, &got)); diff --git a/test/libc/calls/sigprocmask_test.c b/test/libc/calls/sigprocmask_test.c index 94ea33eca..cd8502fc5 100644 --- a/test/libc/calls/sigprocmask_test.c +++ b/test/libc/calls/sigprocmask_test.c @@ -70,7 +70,7 @@ TEST(sigprocmask, testMultipleBlockedDeliveriesOfSameSignal) { EXPECT_EQ(0, n); EXPECT_EQ(0, sigprocmask(SIG_SETMASK, &old, NULL)); EXPECT_EQ(0, sigaction(SIGUSR2, &oldusr2, 0)); - if (IsFreebsd() || IsWindows()) { + if (IsFreebsd()) { EXPECT_EQ(2, n); } else { EXPECT_EQ(1, n);