Introduce interprocess signaling on Windows

This change gets rsync working without any warning or errors. On Windows
we now create a bunch of C:\var\sig\x\y.pid shared memory files, so sigs
can be delivered between processes. WinMain() creates this file when the
process starts. If the program links signaling system calls then we make
a thread at startup too, which allows asynchronous delivery each quantum
and cancelation points can spot these signals potentially faster on wait

See #1240
This commit is contained in:
Justine Tunney 2024-09-19 03:02:13 -07:00
parent 8527462b95
commit 0d74673213
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
22 changed files with 302 additions and 62 deletions

View file

@ -16,16 +16,21 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/atomic.h"
#include "libc/calls/calls.h"
#include "libc/calls/sig.internal.h"
#include "libc/calls/struct/sigset.internal.h"
#include "libc/calls/syscall-nt.internal.h"
#include "libc/errno.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/dll.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/strace.h"
#include "libc/nt/console.h"
#include "libc/nt/enum/ctrlevent.h"
#include "libc/nt/enum/processaccess.h"
#include "libc/nt/errors.h"
#include "libc/nt/memory.h"
#include "libc/nt/process.h"
#include "libc/nt/runtime.h"
#include "libc/proc/proc.internal.h"
@ -36,21 +41,18 @@
textwindows int sys_kill_nt(int pid, int sig) {
// validate api usage
if (!(0 <= sig && sig <= 64)) {
if (!(0 <= sig && sig <= 64))
return einval();
}
// XXX: NT doesn't really have process groups. For instance the
// CreateProcess() flag for starting a process group actually
// just does an "ignore ctrl-c" internally.
if (pid < -1) {
if (pid < -1)
pid = -pid;
}
// no support for kill all yet
if (pid == -1) {
if (pid == -1)
return einval();
}
// just call raise() if we're targeting self
if (pid <= 0 || pid == getpid()) {
@ -70,6 +72,18 @@ textwindows int sys_kill_nt(int pid, int sig) {
}
}
// attempt to signal via /var/sig shared memory file
if (pid > 0 && sig != 9) {
atomic_ulong *sigproc;
if ((sigproc = __sig_map_process(pid))) {
if (sig > 0)
atomic_fetch_or_explicit(sigproc, 1ull << (sig - 1),
memory_order_release);
UnmapViewOfFile(sigproc);
return 0;
}
}
// find existing handle we own for process
int64_t handle, closeme = 0;
if (!(handle = __proc_handle(pid))) {