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/wait.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/events.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/ipc.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) {
|
||||
// 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;
|
||||
filehands[pn] = g_fds.p[fds[i].fd].handle;
|
||||
++pn;
|
||||
|
@ -230,8 +231,8 @@ textwindows static int sys_poll_nt_actual(struct pollfd *fds, uint64_t nfds,
|
|||
if (__sigcheck(waitmask, false))
|
||||
return -1;
|
||||
pt = _pthread_self();
|
||||
filehands[pn] = pt->pt_semaphore = CreateSemaphore(0, 0, 1, 0);
|
||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_SEM,
|
||||
filehands[pn] = pt->pt_event = CreateEvent(0, 0, 0, 0);
|
||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_EVENT,
|
||||
memory_order_release);
|
||||
wi = WaitForMultipleObjects(pn + 1, filehands, 0, waitfor);
|
||||
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
|
||||
return __winerr();
|
||||
} else if (wi == pn) {
|
||||
// our semaphore was signalled
|
||||
// our signal event was signalled
|
||||
if (__sigcheck(waitmask, false))
|
||||
return -1;
|
||||
} else if ((wi ^ kNtWaitAbandoned) < pn) {
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "libc/nt/enum/vk.h"
|
||||
#include "libc/nt/enum/wait.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/events.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/inputrecord.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
|
@ -833,25 +834,39 @@ textwindows static void RestoreProcessedInput(uint32_t inmode) {
|
|||
textwindows static int CountConsoleInputBytesBlockingImpl(uint32_t ms,
|
||||
sigset_t waitmask,
|
||||
bool restartable) {
|
||||
int sig;
|
||||
int64_t sem;
|
||||
uint32_t wi;
|
||||
struct timespec now, deadline;
|
||||
InitConsole();
|
||||
deadline =
|
||||
struct timespec deadline =
|
||||
timespec_add(sys_clock_gettime_monotonic_nt(), timespec_frommillis(ms));
|
||||
RestartOperation:
|
||||
if (_check_cancel() == -1)
|
||||
return -1;
|
||||
if (_weaken(__sig_get) && (sig = _weaken(__sig_get)(waitmask)))
|
||||
goto DeliverSignal;
|
||||
for (;;) {
|
||||
int sig = 0;
|
||||
intptr_t sev;
|
||||
if (!(sev = CreateEvent(0, 0, 0, 0)))
|
||||
return __winerr();
|
||||
struct PosixThread *pt = _pthread_self();
|
||||
pt->pt_event = sev;
|
||||
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, PT_BLOCKER_EVENT,
|
||||
memory_order_release);
|
||||
if (_check_cancel() == -1) {
|
||||
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
||||
CloseHandle(sem);
|
||||
CloseHandle(sev);
|
||||
return -1;
|
||||
}
|
||||
if (_weaken(__sig_get) && (sig = _weaken(__sig_get)(waitmask))) {
|
||||
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
|
||||
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)
|
||||
|
@ -863,35 +878,27 @@ RestartOperation:
|
|||
// 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) {
|
||||
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;
|
||||
}
|
||||
continue;
|
||||
return got;
|
||||
}
|
||||
|
||||
// handle wait itself failing
|
||||
if (wi != 1)
|
||||
return __winerr();
|
||||
|
||||
if (wi == 1 && _weaken(__sig_get) && (sig = _weaken(__sig_get)(waitmask))) {
|
||||
// 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);
|
||||
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)
|
||||
|
@ -900,7 +907,7 @@ RestartOperation:
|
|||
if (!restartable)
|
||||
return eintr();
|
||||
}
|
||||
goto RestartOperation;
|
||||
}
|
||||
}
|
||||
|
||||
textwindows static int CountConsoleInputBytesBlocking(uint32_t ms,
|
||||
|
@ -911,7 +918,7 @@ textwindows static int CountConsoleInputBytesBlocking(uint32_t ms,
|
|||
if (got > 0)
|
||||
return got;
|
||||
uint32_t inmode = DisableProcessedInput();
|
||||
int rc = CountConsoleInputBytesBlockingImpl(ms, waitmask, false);
|
||||
int rc = CountConsoleInputBytesBlockingImpl(ms, waitmask, true);
|
||||
RestoreProcessedInput(inmode);
|
||||
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
|
||||
// it's not safe to acknowledge cancelation from here
|
||||
// it's not safe to call any signal handlers from here
|
||||
intptr_t sem;
|
||||
if ((sem = CreateSemaphore(0, 0, 1, 0))) {
|
||||
intptr_t sigev;
|
||||
if ((sigev = CreateEvent(0, 0, 0, 0))) {
|
||||
// installing semaphore before sig get makes wait atomic
|
||||
struct PosixThread *pt = _pthread_self();
|
||||
pt->pt_semaphore = sem;
|
||||
pt->pt_event = sigev;
|
||||
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);
|
||||
if (_is_canceled()) {
|
||||
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))) {
|
||||
CancelIoEx(handle, &overlap);
|
||||
} else {
|
||||
intptr_t hands[] = {event, sem};
|
||||
intptr_t hands[] = {event, sigev};
|
||||
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);
|
||||
if (_weaken(__sig_get))
|
||||
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);
|
||||
CloseHandle(sem);
|
||||
CloseHandle(sigev);
|
||||
} else {
|
||||
other_error = GetLastError();
|
||||
CancelIoEx(handle, &overlap);
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "libc/nt/enum/exceptionhandleractions.h"
|
||||
#include "libc/nt/enum/signal.h"
|
||||
#include "libc/nt/enum/status.h"
|
||||
#include "libc/nt/events.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/signals.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));
|
||||
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
|
||||
if (blocker == PT_BLOCKER_SEM) {
|
||||
STRACE("%G releasing %d's semaphore", sig, _pthread_tid(pt));
|
||||
ReleaseSemaphore(pt->pt_semaphore, 1, 0);
|
||||
if (blocker == PT_BLOCKER_EVENT) {
|
||||
STRACE("%G set %d's event object", sig, _pthread_tid(pt));
|
||||
SetEvent(pt->pt_event);
|
||||
return;
|
||||
}
|
||||
// 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/intrin/atomic.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/nt/events.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/synchronization.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,
|
||||
const struct timespec *opt_timeout) {
|
||||
int rc;
|
||||
intptr_t sem;
|
||||
intptr_t sev;
|
||||
struct PosixThread *pt;
|
||||
struct timespec deadline;
|
||||
sigset_t syncsigs, waitmask;
|
||||
|
@ -95,17 +96,17 @@ textwindows int sys_sigtimedwait_nt(const sigset_t *set, siginfo_t *opt_info,
|
|||
} else {
|
||||
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
|
||||
waitmask = ~syncsigs & _SigMask;
|
||||
pt = _pthread_self();
|
||||
pt->pt_event = sev;
|
||||
pt->pt_blkmask = waitmask;
|
||||
pt->pt_semaphore = sem = CreateSemaphore(0, 0, 1, 0);
|
||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_SEM,
|
||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_EVENT,
|
||||
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);
|
||||
CloseHandle(sem);
|
||||
CloseHandle(sev);
|
||||
} else {
|
||||
rc = __winerr();
|
||||
}
|
||||
|
|
|
@ -131,15 +131,15 @@ static textwindows int __proc_wait(int pid, int *wstatus, int options,
|
|||
|
||||
// perform blocking operation
|
||||
uint32_t wi;
|
||||
uintptr_t sem;
|
||||
uintptr_t event;
|
||||
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,
|
||||
pt->pt_event = event = CreateEvent(0, 0, 0, 0);
|
||||
atomic_store_explicit(&pt->pt_blocker, PT_BLOCKER_EVENT,
|
||||
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);
|
||||
CloseHandle(sem);
|
||||
CloseHandle(event);
|
||||
|
||||
// log warning if handle unexpectedly closed
|
||||
if (wi & kNtWaitAbandoned) {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/nt/enum/wait.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/events.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/overlapped.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
|
||||
// it's not safe to acknowledge cancelation from here
|
||||
// it's not safe to call any signal handlers from here
|
||||
intptr_t sem;
|
||||
if ((sem = CreateSemaphore(0, 0, 1, 0))) {
|
||||
intptr_t sev;
|
||||
if ((sev = CreateEvent(0, 0, 0, 0))) {
|
||||
// installing semaphore before sig get makes wait atomic
|
||||
struct PosixThread *pt = _pthread_self();
|
||||
pt->pt_semaphore = sem;
|
||||
pt->pt_event = sev;
|
||||
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);
|
||||
if (_is_canceled()) {
|
||||
got_cancel = true;
|
||||
|
@ -94,7 +95,7 @@ __winsock_block(int64_t handle, uint32_t flags, bool nonblock,
|
|||
struct timespec remain = timespec_subz(deadline, now);
|
||||
int64_t millis = timespec_tomillis(remain);
|
||||
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);
|
||||
if (wi == 1) { // semaphore was signaled by signal enqueue
|
||||
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);
|
||||
CloseHandle(sem);
|
||||
CloseHandle(sev);
|
||||
} else {
|
||||
other_error = GetLastError();
|
||||
CancelIoEx(handle, &overlap);
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
||||
#define PT_BLOCKER_SEM ((atomic_int *)-1)
|
||||
#define PT_BLOCKER_IO ((atomic_int *)-2)
|
||||
#define PT_BLOCKER_EVENT ((atomic_int *)-1)
|
||||
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
|
@ -86,10 +85,8 @@ struct PosixThread {
|
|||
struct _pthread_cleanup_buffer *pt_cleanup;
|
||||
_Atomic(atomic_int *) pt_blocker;
|
||||
uint64_t pt_blkmask;
|
||||
int64_t pt_semaphore;
|
||||
intptr_t pt_iohandle;
|
||||
int64_t pt_event;
|
||||
locale_t pt_locale;
|
||||
void *pt_ioverlap;
|
||||
jmp_buf pt_exiter;
|
||||
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/mem/gc.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/efi.h"
|
||||
#include "libc/sock/select.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/struct/pollfd.h"
|
||||
|
|
Loading…
Reference in a new issue