Put more thought into i/o polyfills

wait4() is now solid enough to run `make -j100` on Windows. You can now
use MSG_DONTWAIT on Windows. There was a handle leak in accept() that's
been fixed. Our WIN32 overlapped i/o code has been simplified. Priority
class now inherits into subprocesses, so the verynice command will work
and the signal mask will now be inherited by execve() and posix_spawn()
This commit is contained in:
Justine Tunney 2023-11-06 16:38:44 -08:00
parent 736fdb757a
commit e961385e55
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
52 changed files with 679 additions and 487 deletions

View file

@ -723,8 +723,6 @@ static textwindows int WaitForConsole(struct Fd *f, sigset_t waitmask) {
int sig;
int64_t sem;
uint32_t wi, ms = -1;
int handler_was_called;
struct PosixThread *pt;
if (!__ttyconf.vmin) {
if (!__ttyconf.vtime) {
return 0; // non-blocking w/o raising eagain
@ -732,31 +730,24 @@ static textwindows int WaitForConsole(struct Fd *f, sigset_t waitmask) {
ms = __ttyconf.vtime * 100;
}
}
if (f->flags & _O_NONBLOCK) {
return eagain(); // standard unix non-blocking
}
if (_check_cancel() == -1) return -1;
if ((sig = __sig_get(waitmask))) {
handler_was_called = __sig_relay(sig, SI_KERNEL, waitmask);
if (_check_cancel() == -1) return -1;
if (handler_was_called != 1) return -2;
return eintr();
}
pt = _pthread_self();
pt->pt_semaphore = sem = CreateSemaphore(0, 0, 1, 0);
pthread_cleanup_push((void *)CloseHandle, (void *)sem);
if (f->flags & _O_NONBLOCK) return eagain();
if ((sig = __sig_get(waitmask))) goto DeliverSignal;
struct PosixThread *pt = _pthread_self();
pt->pt_blkmask = waitmask;
pt->pt_semaphore = sem = CreateSemaphore(0, 0, 1, 0);
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_SEM, memory_order_release);
wi = WaitForMultipleObjects(2, (int64_t[2]){__keystroke.cin, sem}, 0, ms);
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
pthread_cleanup_pop(true);
CloseHandle(sem);
if (wi == kNtWaitTimeout) return 0; // vtime elapsed
if (wi == 0) return -2; // console data
if (wi != 1) return __winerr(); // wait failed
if (!(sig = __sig_get(waitmask))) return eintr();
handler_was_called = __sig_relay(sig, SI_KERNEL, waitmask);
DeliverSignal:
int handler_was_called = __sig_relay(sig, SI_KERNEL, waitmask);
if (_check_cancel() == -1) return -1;
if (handler_was_called != 1) return -2;
if (!(handler_was_called & SIG_HANDLED_NO_RESTART)) return -2;
return eintr();
}