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

@ -17,11 +17,25 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/sysv/consts/sig.h"
#include "libc/atomic.h"
#include "libc/calls/sig.internal.h"
#include "libc/calls/struct/sigset.internal.h"
#include "libc/dce.h"
#include "libc/fmt/internal.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/weaken.h"
#include "libc/limits.h"
#include "libc/nt/createfile.h"
#include "libc/nt/enum/accessmask.h"
#include "libc/nt/enum/creationdisposition.h"
#include "libc/nt/enum/fileflagandattributes.h"
#include "libc/nt/enum/filemapflags.h"
#include "libc/nt/enum/filemovemethod.h"
#include "libc/nt/enum/filesharemode.h"
#include "libc/nt/enum/pageflags.h"
#include "libc/nt/files.h"
#include "libc/nt/memory.h"
#include "libc/nt/runtime.h"
#include "libc/thread/tls.h"
struct Signals __sig;
@ -52,3 +66,65 @@ void __sig_unblock(sigset_t m) {
sys_sigprocmask(SIG_SETMASK, &m, 0);
}
}
#ifdef __x86_64__
textwindows char16_t *__sig_process_path(char16_t *path, uint32_t pid) {
char16_t *p = path;
*p++ = 'C';
*p++ = ':';
*p++ = '\\';
*p++ = 'v';
*p++ = 'a';
*p++ = 'r';
*p = 0;
CreateDirectory(path, 0);
*p++ = '\\';
*p++ = 's';
*p++ = 'i';
*p++ = 'g';
*p = 0;
CreateDirectory(path, 0);
*p++ = '\\';
p = __itoa16(p, (pid & 0x000fff00) >> 8);
*p = 0;
CreateDirectory(path, 0);
*p++ = '\\';
p = __itoa16(p, pid);
*p++ = '.';
*p++ = 'p';
*p++ = 'i';
*p++ = 'd';
*p = 0;
return path;
}
textwindows static atomic_ulong *__sig_map_process_impl(int pid) {
char16_t path[128];
intptr_t hand = CreateFile(__sig_process_path(path, pid),
kNtGenericRead | kNtGenericWrite,
kNtFileShareRead | kNtFileShareWrite, 0,
kNtOpenAlways, kNtFileAttributeNormal, 0);
if (hand == -1)
return 0;
SetFilePointer(hand, 8, 0, kNtFileBegin);
SetEndOfFile(hand);
intptr_t map = CreateFileMapping(hand, 0, kNtPageReadwrite, 0, 8, 0);
if (!map) {
CloseHandle(hand);
return 0;
}
atomic_ulong *sigs = MapViewOfFileEx(map, kNtFileMapWrite, 0, 0, 8, 0);
CloseHandle(map);
CloseHandle(hand);
return sigs;
}
textwindows atomic_ulong *__sig_map_process(int pid) {
int e = errno;
atomic_ulong *res = __sig_map_process_impl(pid);
errno = e;
return res;
}
#endif /* __x86_64__ */