diff --git a/libc/intrin/mmap.c b/libc/intrin/mmap.c index b37364092e7..6f246e07b2b 100644 --- a/libc/intrin/mmap.c +++ b/libc/intrin/mmap.c @@ -660,7 +660,7 @@ static void *__mmap_impl(char *addr, size_t size, int prot, int flags, int fd, if (!IsWindows()) { struct Map *deleted = 0; __maps_lock(); - if (IsWindows() || fixedmode) + if (fixedmode) if (__muntrack(res.addr, size, &deleted, 0, 0)) STRACE("memtrack compromised by hole punch oom"); __maps_insert(map); diff --git a/libc/intrin/sig.c b/libc/intrin/sig.c index 4f0b15f81cb..9503a4a5da0 100644 --- a/libc/intrin/sig.c +++ b/libc/intrin/sig.c @@ -492,9 +492,8 @@ textwindows void __sig_generate(int sig, int sic) { __sig_terminate(sig); } if (atomic_load_explicit(__sig.process, memory_order_acquire) & - (1ull << (sig - 1))) { + (1ull << (sig - 1))) return; - } _pthread_lock(); for (e = dll_first(_pthread_list); e; e = dll_next(_pthread_list, e)) { pt = POSIXTHREAD_CONTAINER(e); @@ -503,9 +502,8 @@ textwindows void __sig_generate(int sig, int sic) { continue; // we don't want to signal a thread that isn't running if (atomic_load_explicit(&pt->pt_status, memory_order_acquire) >= - kPosixThreadTerminated) { + kPosixThreadTerminated) continue; - } // choose this thread if it isn't masking sig if (!(atomic_load_explicit(&pt->tib->tib_sigmask, memory_order_acquire) & (1ull << (sig - 1)))) { @@ -756,11 +754,26 @@ HAIRY static uint32_t __sig_worker(void *arg) { __sig_generate(sig, SI_KERNEL); } + // unblock stalled i/o signals in threads + _pthread_lock(); + for (struct Dll *e = dll_first(_pthread_list); e; + e = dll_next(_pthread_list, e)) { + struct PosixThread *pt = POSIXTHREAD_CONTAINER(e); + if (atomic_load_explicit(&pt->pt_status, memory_order_acquire) >= + kPosixThreadTerminated) + break; + if (atomic_load_explicit(&pt->pt_blocker, memory_order_acquire) && + (atomic_load_explicit(&pt->tib->tib_sigpending, + memory_order_acquire) & + ~atomic_load_explicit(&pt->pt_blkmask, memory_order_acquire))) + __sig_wake(pt, 0); + } + _pthread_unlock(); + // unblock stalled asynchronous signals in threads - struct PosixThread *mark; for (;;) { sigset_t pending, mask; - mark = 0; + struct PosixThread *mark = 0; _pthread_lock(); for (struct Dll *e = dll_first(_pthread_list); e; e = dll_next(_pthread_list, e)) { @@ -790,6 +803,7 @@ HAIRY static uint32_t __sig_worker(void *arg) { pending &= ~(1ull << (sig - 1)); __sig_killer(mark, sig, SI_KERNEL); } + _pthread_unref(mark); } // wait until next scheduler quantum diff --git a/test/posix/sa_resethand2_test.c b/test/posix/sa_resethand2_test.c index c66f8cb8d83..3a6dc34dac0 100644 --- a/test/posix/sa_resethand2_test.c +++ b/test/posix/sa_resethand2_test.c @@ -1,27 +1,20 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│ vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi │ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ 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 │ -│ 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/struct/sigaction.h" -#include "libc/calls/struct/sigset.h" -#include "libc/dce.h" -#include "libc/sysv/consts/sa.h" -#include "libc/sysv/consts/sig.h" +// Copyright 2024 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 +#include volatile int handler_invoked; @@ -33,24 +26,17 @@ int main() { sigset_t mask, oldmask; struct sigaction sa, current_sa; - if (IsWindows()) { - // TODO(jart): support non-fatal signals between processes - return 0; - } - sa.sa_handler = signal_handler; sa.sa_flags = SA_RESETHAND; sigemptyset(&sa.sa_mask); - if (sigaction(SIGINT, &sa, 0) == -1) { + if (sigaction(SIGINT, &sa, 0) == -1) return 1; - } sigemptyset(&mask); sigaddset(&mask, SIGINT); - if (sigprocmask(SIG_BLOCK, &mask, &oldmask) == -1) { + if (sigprocmask(SIG_BLOCK, &mask, &oldmask) == -1) return 2; - } int pid = fork(); if (pid == -1) { @@ -60,15 +46,12 @@ int main() { return 0; } else { sigsuspend(&oldmask); - if (!handler_invoked) { + if (!handler_invoked) return 4; - } - if (sigaction(SIGINT, 0, ¤t_sa) == -1) { + if (sigaction(SIGINT, 0, ¤t_sa) == -1) return 5; - } - if (current_sa.sa_handler != SIG_DFL) { + if (current_sa.sa_handler != SIG_DFL) return 6; - } return 0; } } diff --git a/test/posix/signal_latency_test.c b/test/posix/signal_latency_test.c index 080e1fd97bb..aa73cb77128 100644 --- a/test/posix/signal_latency_test.c +++ b/test/posix/signal_latency_test.c @@ -133,10 +133,6 @@ int main() { if (IsOpenbsd()) return 0; - // TODO(jart): Why is this test flaky on Windows? - if (IsWindows()) - return 0; - // Block SIGUSR1 and SIGUSR2 in main thread sigset_t block_set; sigemptyset(&block_set);