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,11 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/atomic.h"
#include "libc/calls/internal.h"
#include "libc/calls/sig.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/intrin/dll.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/maps.h"
#include "libc/intrin/nomultics.h"
#include "libc/intrin/weaken.h"
@ -294,7 +294,6 @@ static abi wontreturn void WinInit(const char16_t *cmdline) {
ARRAYLEN(wa->envp) - 1);
__imp_FreeEnvironmentStringsW(env16);
__envp = &wa->envp[0];
// handover control to cosmopolitan runtime
__stack_call(count, wa->argv, wa->envp, wa->auxv, cosmo,
(uintptr_t)(stackaddr + (stacksize - sizeof(struct WinArgs))));
@ -302,6 +301,7 @@ static abi wontreturn void WinInit(const char16_t *cmdline) {
abi int64_t WinMain(int64_t hInstance, int64_t hPrevInstance,
const char *lpCmdLine, int64_t nCmdShow) {
static atomic_ulong fake_process_signals;
const char16_t *cmdline;
extern char os asm("__hostos");
os = _HOSTWINDOWS; // madness https://news.ycombinator.com/item?id=21019722
@ -317,19 +317,20 @@ abi int64_t WinMain(int64_t hInstance, int64_t hPrevInstance,
__gransize = si.dwAllocationGranularity;
__umask = 077;
__pid = __imp_GetCurrentProcessId();
if (!(__sig.process = __sig_map_process(__pid)))
__sig.process = &fake_process_signals;
atomic_store_explicit(__sig.process, 0, memory_order_release);
cmdline = __imp_GetCommandLineW();
#if SYSDEBUG
// sloppy flag-only check for early initialization
if (StrStr(cmdline, u"--strace"))
++__strace;
#endif
if (_weaken(WinSockInit)) {
if (_weaken(WinSockInit))
_weaken(WinSockInit)();
}
DeduplicateStdioHandles();
if (_weaken(WinMainForked)) {
if (_weaken(WinMainForked))
_weaken(WinMainForked)();
}
WinInit(cmdline);
}