mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Clean up more code
This commit is contained in:
parent
baf70af780
commit
949c398327
9 changed files with 108 additions and 107 deletions
|
@ -30,6 +30,7 @@
|
||||||
#include "libc/nt/enum/filetype.h"
|
#include "libc/nt/enum/filetype.h"
|
||||||
#include "libc/nt/enum/wait.h"
|
#include "libc/nt/enum/wait.h"
|
||||||
#include "libc/nt/errors.h"
|
#include "libc/nt/errors.h"
|
||||||
|
#include "libc/nt/events.h"
|
||||||
#include "libc/nt/files.h"
|
#include "libc/nt/files.h"
|
||||||
#include "libc/nt/ipc.h"
|
#include "libc/nt/ipc.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
|
@ -114,7 +115,7 @@ textwindows static int sys_poll_nt_actual(struct pollfd *fds, uint64_t nfds,
|
||||||
}
|
}
|
||||||
} else if (kind == kFdFile || kind == kFdConsole) {
|
} else if (kind == kFdFile || kind == kFdConsole) {
|
||||||
// we can use WaitForMultipleObjects() for these fds
|
// we can use WaitForMultipleObjects() for these fds
|
||||||
if (pn < ARRAYLEN(fileindices) - 1) { // last slot for semaphore
|
if (pn < ARRAYLEN(fileindices) - 1) { // last slot for signal event
|
||||||
fileindices[pn] = i;
|
fileindices[pn] = i;
|
||||||
filehands[pn] = g_fds.p[fds[i].fd].handle;
|
filehands[pn] = g_fds.p[fds[i].fd].handle;
|
||||||
++pn;
|
++pn;
|
||||||
|
@ -230,8 +231,8 @@ textwindows static int sys_poll_nt_actual(struct pollfd *fds, uint64_t nfds,
|
||||||
if (__sigcheck(waitmask, false))
|
if (__sigcheck(waitmask, false))
|
||||||
return -1;
|
return -1;
|
||||||
pt = _pthread_self();
|
pt = _pthread_self();
|
||||||
filehands[pn] = pt->pt_semaphore = CreateSemaphore(0, 0, 1, 0);
|
filehands[pn] = pt->pt_event = CreateEvent(0, 0, 0, 0);
|
||||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_SEM,
|
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_EVENT,
|
||||||
memory_order_release);
|
memory_order_release);
|
||||||
wi = WaitForMultipleObjects(pn + 1, filehands, 0, waitfor);
|
wi = WaitForMultipleObjects(pn + 1, filehands, 0, waitfor);
|
||||||
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
||||||
|
@ -240,7 +241,7 @@ textwindows static int sys_poll_nt_actual(struct pollfd *fds, uint64_t nfds,
|
||||||
// win32 wait failure
|
// win32 wait failure
|
||||||
return __winerr();
|
return __winerr();
|
||||||
} else if (wi == pn) {
|
} else if (wi == pn) {
|
||||||
// our semaphore was signalled
|
// our signal event was signalled
|
||||||
if (__sigcheck(waitmask, false))
|
if (__sigcheck(waitmask, false))
|
||||||
return -1;
|
return -1;
|
||||||
} else if ((wi ^ kNtWaitAbandoned) < pn) {
|
} else if ((wi ^ kNtWaitAbandoned) < pn) {
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "libc/nt/enum/vk.h"
|
#include "libc/nt/enum/vk.h"
|
||||||
#include "libc/nt/enum/wait.h"
|
#include "libc/nt/enum/wait.h"
|
||||||
#include "libc/nt/errors.h"
|
#include "libc/nt/errors.h"
|
||||||
|
#include "libc/nt/events.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/nt/struct/inputrecord.h"
|
#include "libc/nt/struct/inputrecord.h"
|
||||||
#include "libc/nt/synchronization.h"
|
#include "libc/nt/synchronization.h"
|
||||||
|
@ -833,74 +834,80 @@ textwindows static void RestoreProcessedInput(uint32_t inmode) {
|
||||||
textwindows static int CountConsoleInputBytesBlockingImpl(uint32_t ms,
|
textwindows static int CountConsoleInputBytesBlockingImpl(uint32_t ms,
|
||||||
sigset_t waitmask,
|
sigset_t waitmask,
|
||||||
bool restartable) {
|
bool restartable) {
|
||||||
int sig;
|
|
||||||
int64_t sem;
|
|
||||||
uint32_t wi;
|
|
||||||
struct timespec now, deadline;
|
|
||||||
InitConsole();
|
InitConsole();
|
||||||
deadline =
|
struct timespec deadline =
|
||||||
timespec_add(sys_clock_gettime_monotonic_nt(), timespec_frommillis(ms));
|
timespec_add(sys_clock_gettime_monotonic_nt(), timespec_frommillis(ms));
|
||||||
RestartOperation:
|
for (;;) {
|
||||||
if (_check_cancel() == -1)
|
int sig = 0;
|
||||||
return -1;
|
intptr_t sev;
|
||||||
if (_weaken(__sig_get) && (sig = _weaken(__sig_get)(waitmask)))
|
if (!(sev = CreateEvent(0, 0, 0, 0)))
|
||||||
goto DeliverSignal;
|
return __winerr();
|
||||||
struct PosixThread *pt = _pthread_self();
|
struct PosixThread *pt = _pthread_self();
|
||||||
pt->pt_blkmask = waitmask;
|
pt->pt_event = sev;
|
||||||
pt->pt_semaphore = sem = CreateSemaphore(0, 0, 1, 0);
|
pt->pt_blkmask = waitmask;
|
||||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_SEM, memory_order_release);
|
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_EVENT,
|
||||||
wi = WaitForMultipleObjects(2, (int64_t[2]){__keystroke.cin, sem}, 0, ms);
|
memory_order_release);
|
||||||
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
if (_check_cancel() == -1) {
|
||||||
CloseHandle(sem);
|
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
||||||
|
CloseHandle(sev);
|
||||||
// check for wait timeout
|
|
||||||
if (wi == kNtWaitTimeout)
|
|
||||||
return etimedout();
|
|
||||||
|
|
||||||
// handle event on console handle. this means we can now read from the
|
|
||||||
// conosle without blocking. so the first thing we do is slurp up your
|
|
||||||
// keystroke data. some of those keystrokes might cause a signal to be
|
|
||||||
// raised. so we need to check for pending signals again and handle it
|
|
||||||
if (wi == 0) {
|
|
||||||
int got = CountConsoleInputBytes();
|
|
||||||
if (_weaken(__sig_get) && (sig = _weaken(__sig_get)(waitmask)))
|
|
||||||
goto DeliverSignal;
|
|
||||||
if (got == -1)
|
|
||||||
// this is a bona fide eof and console errors are logged to strace
|
|
||||||
return 0;
|
|
||||||
if (got == 0) {
|
|
||||||
// this can happen for multiple reasons. first our driver controls
|
|
||||||
// user interactions in canonical mode. secondly we could lose the
|
|
||||||
// race with another thread that's reading input.
|
|
||||||
now = sys_clock_gettime_monotonic_nt();
|
|
||||||
if (timespec_cmp(now, deadline) >= 0)
|
|
||||||
return etimedout();
|
|
||||||
ms = timespec_tomillis(timespec_sub(deadline, now));
|
|
||||||
ms = ms > -1u ? -1u : ms;
|
|
||||||
goto RestartOperation;
|
|
||||||
}
|
|
||||||
return got;
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle wait itself failing
|
|
||||||
if (wi != 1)
|
|
||||||
return __winerr();
|
|
||||||
|
|
||||||
// handle event on throwaway semaphore, it is poked by signal delivery
|
|
||||||
if (_weaken(__sig_get)) {
|
|
||||||
if (!(sig = _weaken(__sig_get)(waitmask)))
|
|
||||||
return eintr();
|
|
||||||
DeliverSignal:
|
|
||||||
int handler_was_called = _weaken(__sig_relay)(sig, SI_KERNEL, waitmask);
|
|
||||||
if (_check_cancel() == -1)
|
|
||||||
return -1;
|
return -1;
|
||||||
if (handler_was_called & SIG_HANDLED_NO_RESTART)
|
}
|
||||||
return eintr();
|
if (_weaken(__sig_get) && (sig = _weaken(__sig_get)(waitmask))) {
|
||||||
if (handler_was_called & SIG_HANDLED_SA_RESTART)
|
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
||||||
if (!restartable)
|
CloseHandle(sev);
|
||||||
|
goto DeliverSignal;
|
||||||
|
}
|
||||||
|
struct timespec now = sys_clock_gettime_monotonic_nt();
|
||||||
|
struct timespec remain = timespec_subz(deadline, now);
|
||||||
|
int64_t millis = timespec_tomillis(remain);
|
||||||
|
uint32_t waitms = MIN(millis, 0xffffffffu);
|
||||||
|
intptr_t hands[] = {__keystroke.cin, sev};
|
||||||
|
uint32_t wi = WaitForMultipleObjects(2, hands, 0, waitms);
|
||||||
|
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
||||||
|
CloseHandle(sev);
|
||||||
|
if (wi == -1u)
|
||||||
|
return __winerr();
|
||||||
|
|
||||||
|
// check for wait timeout
|
||||||
|
if (wi == kNtWaitTimeout)
|
||||||
|
return etimedout();
|
||||||
|
|
||||||
|
// handle event on console handle. this means we can now read from the
|
||||||
|
// conosle without blocking. so the first thing we do is slurp up your
|
||||||
|
// keystroke data. some of those keystrokes might cause a signal to be
|
||||||
|
// raised. so we need to check for pending signals again and handle it
|
||||||
|
if (wi == 0) {
|
||||||
|
int got = CountConsoleInputBytes();
|
||||||
|
// we might have read a keystroke that generated a signal
|
||||||
|
if (_weaken(__sig_get) && (sig = _weaken(__sig_get)(waitmask)))
|
||||||
|
goto DeliverSignal;
|
||||||
|
if (got == -1)
|
||||||
|
// this is a bona fide eof and console errors are logged to strace
|
||||||
|
return 0;
|
||||||
|
if (got == 0)
|
||||||
|
// this can happen for multiple reasons. first our driver controls
|
||||||
|
// user interactions in canonical mode. secondly we could lose the
|
||||||
|
// race with another thread that's reading input.
|
||||||
|
continue;
|
||||||
|
return got;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wi == 1 && _weaken(__sig_get) && (sig = _weaken(__sig_get)(waitmask))) {
|
||||||
|
// handle event on throwaway semaphore, it is poked by signal delivery
|
||||||
|
DeliverSignal:;
|
||||||
|
int handler_was_called = 0;
|
||||||
|
do {
|
||||||
|
handler_was_called |= _weaken(__sig_relay)(sig, SI_KERNEL, waitmask);
|
||||||
|
} while ((sig = _weaken(__sig_get)(waitmask)));
|
||||||
|
if (_check_cancel() == -1)
|
||||||
|
return -1;
|
||||||
|
if (handler_was_called & SIG_HANDLED_NO_RESTART)
|
||||||
return eintr();
|
return eintr();
|
||||||
|
if (handler_was_called & SIG_HANDLED_SA_RESTART)
|
||||||
|
if (!restartable)
|
||||||
|
return eintr();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
goto RestartOperation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
textwindows static int CountConsoleInputBytesBlocking(uint32_t ms,
|
textwindows static int CountConsoleInputBytesBlocking(uint32_t ms,
|
||||||
|
@ -911,7 +918,7 @@ textwindows static int CountConsoleInputBytesBlocking(uint32_t ms,
|
||||||
if (got > 0)
|
if (got > 0)
|
||||||
return got;
|
return got;
|
||||||
uint32_t inmode = DisableProcessedInput();
|
uint32_t inmode = DisableProcessedInput();
|
||||||
int rc = CountConsoleInputBytesBlockingImpl(ms, waitmask, false);
|
int rc = CountConsoleInputBytesBlockingImpl(ms, waitmask, true);
|
||||||
RestoreProcessedInput(inmode);
|
RestoreProcessedInput(inmode);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,13 +104,13 @@ sys_readwrite_nt(int fd, void *data, size_t size, ssize_t offset,
|
||||||
// atomic block on i/o completion, signal, or cancel
|
// atomic block on i/o completion, signal, or cancel
|
||||||
// it's not safe to acknowledge cancelation from here
|
// it's not safe to acknowledge cancelation from here
|
||||||
// it's not safe to call any signal handlers from here
|
// it's not safe to call any signal handlers from here
|
||||||
intptr_t sem;
|
intptr_t sigev;
|
||||||
if ((sem = CreateSemaphore(0, 0, 1, 0))) {
|
if ((sigev = CreateEvent(0, 0, 0, 0))) {
|
||||||
// installing semaphore before sig get makes wait atomic
|
// installing semaphore before sig get makes wait atomic
|
||||||
struct PosixThread *pt = _pthread_self();
|
struct PosixThread *pt = _pthread_self();
|
||||||
pt->pt_semaphore = sem;
|
pt->pt_event = sigev;
|
||||||
pt->pt_blkmask = waitmask;
|
pt->pt_blkmask = waitmask;
|
||||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_SEM,
|
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_EVENT,
|
||||||
memory_order_release);
|
memory_order_release);
|
||||||
if (_is_canceled()) {
|
if (_is_canceled()) {
|
||||||
CancelIoEx(handle, &overlap);
|
CancelIoEx(handle, &overlap);
|
||||||
|
@ -118,9 +118,9 @@ sys_readwrite_nt(int fd, void *data, size_t size, ssize_t offset,
|
||||||
(got_sig = _weaken(__sig_get)(waitmask))) {
|
(got_sig = _weaken(__sig_get)(waitmask))) {
|
||||||
CancelIoEx(handle, &overlap);
|
CancelIoEx(handle, &overlap);
|
||||||
} else {
|
} else {
|
||||||
intptr_t hands[] = {event, sem};
|
intptr_t hands[] = {event, sigev};
|
||||||
uint32_t wi = WaitForMultipleObjects(2, hands, 0, -1u);
|
uint32_t wi = WaitForMultipleObjects(2, hands, 0, -1u);
|
||||||
if (wi == 1) { // semaphore was signaled by signal enqueue
|
if (wi == 1) { // event was signaled by signal enqueue
|
||||||
CancelIoEx(handle, &overlap);
|
CancelIoEx(handle, &overlap);
|
||||||
if (_weaken(__sig_get))
|
if (_weaken(__sig_get))
|
||||||
got_sig = _weaken(__sig_get)(waitmask);
|
got_sig = _weaken(__sig_get)(waitmask);
|
||||||
|
@ -130,7 +130,7 @@ sys_readwrite_nt(int fd, void *data, size_t size, ssize_t offset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
||||||
CloseHandle(sem);
|
CloseHandle(sigev);
|
||||||
} else {
|
} else {
|
||||||
other_error = GetLastError();
|
other_error = GetLastError();
|
||||||
CancelIoEx(handle, &overlap);
|
CancelIoEx(handle, &overlap);
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "libc/nt/enum/exceptionhandleractions.h"
|
#include "libc/nt/enum/exceptionhandleractions.h"
|
||||||
#include "libc/nt/enum/signal.h"
|
#include "libc/nt/enum/signal.h"
|
||||||
#include "libc/nt/enum/status.h"
|
#include "libc/nt/enum/status.h"
|
||||||
|
#include "libc/nt/events.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/nt/signals.h"
|
#include "libc/nt/signals.h"
|
||||||
#include "libc/nt/struct/ntexceptionpointers.h"
|
#include "libc/nt/struct/ntexceptionpointers.h"
|
||||||
|
@ -230,16 +231,10 @@ textwindows void __sig_cancel(struct PosixThread *pt, int sig, unsigned flags) {
|
||||||
STRACE("%G sent to %d asynchronously", sig, _pthread_tid(pt));
|
STRACE("%G sent to %d asynchronously", sig, _pthread_tid(pt));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// we can cancel another thread's overlapped i/o op after the freeze
|
|
||||||
if (blocker == PT_BLOCKER_IO) {
|
|
||||||
STRACE("%G canceling %d's i/o", sig, _pthread_tid(pt));
|
|
||||||
CancelIoEx(pt->pt_iohandle, pt->pt_ioverlap);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// threads can create semaphores on an as-needed basis
|
// threads can create semaphores on an as-needed basis
|
||||||
if (blocker == PT_BLOCKER_SEM) {
|
if (blocker == PT_BLOCKER_EVENT) {
|
||||||
STRACE("%G releasing %d's semaphore", sig, _pthread_tid(pt));
|
STRACE("%G set %d's event object", sig, _pthread_tid(pt));
|
||||||
ReleaseSemaphore(pt->pt_semaphore, 1, 0);
|
SetEvent(pt->pt_event);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// all other blocking ops that aren't overlap should use futexes
|
// all other blocking ops that aren't overlap should use futexes
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "libc/calls/syscall_support-nt.internal.h"
|
#include "libc/calls/syscall_support-nt.internal.h"
|
||||||
#include "libc/intrin/atomic.h"
|
#include "libc/intrin/atomic.h"
|
||||||
#include "libc/macros.h"
|
#include "libc/macros.h"
|
||||||
|
#include "libc/nt/events.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/nt/synchronization.h"
|
#include "libc/nt/synchronization.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
@ -85,7 +86,7 @@ textwindows static int sys_sigtimedwait_nt_impl(sigset_t syncsigs,
|
||||||
textwindows int sys_sigtimedwait_nt(const sigset_t *set, siginfo_t *opt_info,
|
textwindows int sys_sigtimedwait_nt(const sigset_t *set, siginfo_t *opt_info,
|
||||||
const struct timespec *opt_timeout) {
|
const struct timespec *opt_timeout) {
|
||||||
int rc;
|
int rc;
|
||||||
intptr_t sem;
|
intptr_t sev;
|
||||||
struct PosixThread *pt;
|
struct PosixThread *pt;
|
||||||
struct timespec deadline;
|
struct timespec deadline;
|
||||||
sigset_t syncsigs, waitmask;
|
sigset_t syncsigs, waitmask;
|
||||||
|
@ -95,17 +96,17 @@ textwindows int sys_sigtimedwait_nt(const sigset_t *set, siginfo_t *opt_info,
|
||||||
} else {
|
} else {
|
||||||
deadline = timespec_max;
|
deadline = timespec_max;
|
||||||
}
|
}
|
||||||
if ((sem = CreateSemaphore(0, 0, 1, 0))) {
|
if ((sev = CreateEvent(0, 0, 0, 0))) {
|
||||||
syncsigs = *set & ~(1ull << (SIGTHR - 1)); // internal to pthreads
|
syncsigs = *set & ~(1ull << (SIGTHR - 1)); // internal to pthreads
|
||||||
waitmask = ~syncsigs & _SigMask;
|
waitmask = ~syncsigs & _SigMask;
|
||||||
pt = _pthread_self();
|
pt = _pthread_self();
|
||||||
|
pt->pt_event = sev;
|
||||||
pt->pt_blkmask = waitmask;
|
pt->pt_blkmask = waitmask;
|
||||||
pt->pt_semaphore = sem = CreateSemaphore(0, 0, 1, 0);
|
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_EVENT,
|
||||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_SEM,
|
|
||||||
memory_order_release);
|
memory_order_release);
|
||||||
rc = sys_sigtimedwait_nt_impl(syncsigs, opt_info, deadline, waitmask, sem);
|
rc = sys_sigtimedwait_nt_impl(syncsigs, opt_info, deadline, waitmask, sev);
|
||||||
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
||||||
CloseHandle(sem);
|
CloseHandle(sev);
|
||||||
} else {
|
} else {
|
||||||
rc = __winerr();
|
rc = __winerr();
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,15 +131,15 @@ static textwindows int __proc_wait(int pid, int *wstatus, int options,
|
||||||
|
|
||||||
// perform blocking operation
|
// perform blocking operation
|
||||||
uint32_t wi;
|
uint32_t wi;
|
||||||
uintptr_t sem;
|
uintptr_t event;
|
||||||
struct PosixThread *pt = _pthread_self();
|
struct PosixThread *pt = _pthread_self();
|
||||||
pt->pt_blkmask = waitmask;
|
pt->pt_blkmask = waitmask;
|
||||||
pt->pt_semaphore = sem = CreateSemaphore(0, 0, 1, 0);
|
pt->pt_event = event = CreateEvent(0, 0, 0, 0);
|
||||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_SEM,
|
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_EVENT,
|
||||||
memory_order_release);
|
memory_order_release);
|
||||||
wi = WaitForMultipleObjects(2, (intptr_t[2]){hWaitObject, sem}, 0, -1u);
|
wi = WaitForMultipleObjects(2, (intptr_t[2]){hWaitObject, event}, 0, -1u);
|
||||||
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
||||||
CloseHandle(sem);
|
CloseHandle(event);
|
||||||
|
|
||||||
// log warning if handle unexpectedly closed
|
// log warning if handle unexpectedly closed
|
||||||
if (wi & kNtWaitAbandoned) {
|
if (wi & kNtWaitAbandoned) {
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "libc/intrin/weaken.h"
|
#include "libc/intrin/weaken.h"
|
||||||
#include "libc/nt/enum/wait.h"
|
#include "libc/nt/enum/wait.h"
|
||||||
#include "libc/nt/errors.h"
|
#include "libc/nt/errors.h"
|
||||||
|
#include "libc/nt/events.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/nt/struct/overlapped.h"
|
#include "libc/nt/struct/overlapped.h"
|
||||||
#include "libc/nt/synchronization.h"
|
#include "libc/nt/synchronization.h"
|
||||||
|
@ -75,13 +76,13 @@ __winsock_block(int64_t handle, uint32_t flags, bool nonblock,
|
||||||
// atomic block on i/o completion, signal, or cancel
|
// atomic block on i/o completion, signal, or cancel
|
||||||
// it's not safe to acknowledge cancelation from here
|
// it's not safe to acknowledge cancelation from here
|
||||||
// it's not safe to call any signal handlers from here
|
// it's not safe to call any signal handlers from here
|
||||||
intptr_t sem;
|
intptr_t sev;
|
||||||
if ((sem = CreateSemaphore(0, 0, 1, 0))) {
|
if ((sev = CreateEvent(0, 0, 0, 0))) {
|
||||||
// installing semaphore before sig get makes wait atomic
|
// installing semaphore before sig get makes wait atomic
|
||||||
struct PosixThread *pt = _pthread_self();
|
struct PosixThread *pt = _pthread_self();
|
||||||
pt->pt_semaphore = sem;
|
pt->pt_event = sev;
|
||||||
pt->pt_blkmask = waitmask;
|
pt->pt_blkmask = waitmask;
|
||||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_SEM,
|
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_EVENT,
|
||||||
memory_order_release);
|
memory_order_release);
|
||||||
if (_is_canceled()) {
|
if (_is_canceled()) {
|
||||||
got_cancel = true;
|
got_cancel = true;
|
||||||
|
@ -94,7 +95,7 @@ __winsock_block(int64_t handle, uint32_t flags, bool nonblock,
|
||||||
struct timespec remain = timespec_subz(deadline, now);
|
struct timespec remain = timespec_subz(deadline, now);
|
||||||
int64_t millis = timespec_tomillis(remain);
|
int64_t millis = timespec_tomillis(remain);
|
||||||
uint32_t waitms = MIN(millis, 0xffffffffu);
|
uint32_t waitms = MIN(millis, 0xffffffffu);
|
||||||
intptr_t hands[] = {event, sem};
|
intptr_t hands[] = {event, sev};
|
||||||
uint32_t wi = WSAWaitForMultipleEvents(2, hands, 0, waitms, 0);
|
uint32_t wi = WSAWaitForMultipleEvents(2, hands, 0, waitms, 0);
|
||||||
if (wi == 1) { // semaphore was signaled by signal enqueue
|
if (wi == 1) { // semaphore was signaled by signal enqueue
|
||||||
CancelIoEx(handle, &overlap);
|
CancelIoEx(handle, &overlap);
|
||||||
|
@ -109,7 +110,7 @@ __winsock_block(int64_t handle, uint32_t flags, bool nonblock,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
||||||
CloseHandle(sem);
|
CloseHandle(sev);
|
||||||
} else {
|
} else {
|
||||||
other_error = GetLastError();
|
other_error = GetLastError();
|
||||||
CancelIoEx(handle, &overlap);
|
CancelIoEx(handle, &overlap);
|
||||||
|
|
|
@ -9,8 +9,7 @@
|
||||||
#include "libc/thread/thread.h"
|
#include "libc/thread/thread.h"
|
||||||
#include "libc/thread/tls.h"
|
#include "libc/thread/tls.h"
|
||||||
|
|
||||||
#define PT_BLOCKER_SEM ((atomic_int *)-1)
|
#define PT_BLOCKER_EVENT ((atomic_int *)-1)
|
||||||
#define PT_BLOCKER_IO ((atomic_int *)-2)
|
|
||||||
|
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
@ -86,10 +85,8 @@ struct PosixThread {
|
||||||
struct _pthread_cleanup_buffer *pt_cleanup;
|
struct _pthread_cleanup_buffer *pt_cleanup;
|
||||||
_Atomic(atomic_int *) pt_blocker;
|
_Atomic(atomic_int *) pt_blocker;
|
||||||
uint64_t pt_blkmask;
|
uint64_t pt_blkmask;
|
||||||
int64_t pt_semaphore;
|
int64_t pt_event;
|
||||||
intptr_t pt_iohandle;
|
|
||||||
locale_t pt_locale;
|
locale_t pt_locale;
|
||||||
void *pt_ioverlap;
|
|
||||||
jmp_buf pt_exiter;
|
jmp_buf pt_exiter;
|
||||||
pthread_attr_t pt_attr;
|
pthread_attr_t pt_attr;
|
||||||
};
|
};
|
||||||
|
|
1
third_party/python/Modules/selectmodule.c
vendored
1
third_party/python/Modules/selectmodule.c
vendored
|
@ -9,7 +9,6 @@
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/mem/gc.h"
|
#include "libc/mem/gc.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/nt/efi.h"
|
|
||||||
#include "libc/sock/select.h"
|
#include "libc/sock/select.h"
|
||||||
#include "libc/sock/sock.h"
|
#include "libc/sock/sock.h"
|
||||||
#include "libc/sock/struct/pollfd.h"
|
#include "libc/sock/struct/pollfd.h"
|
||||||
|
|
Loading…
Reference in a new issue