Rewrite Windows accept()

This change should fix the Windows issues Qt Creator has been having, by
ensuring accept() and accept4() work in O_NONBLOCK mode. I switched away
from AcceptEx() which is buggy, back to using WSAAccept(). This requires
making a tradeoff where we have to accept a busy loop. However it is low
latency in nature, just like our new and improved Windows poll() code. I
was furthermore able to eliminate a bunch of Windows-related test todos.
This commit is contained in:
Justine Tunney 2024-09-12 01:18:14 -07:00
parent 6f868fe1de
commit acd6c32184
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
20 changed files with 622 additions and 209 deletions

View file

@ -17,25 +17,19 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/internal.h"
#include "libc/calls/sig.internal.h"
#include "libc/calls/struct/sigset.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/weaken.h"
#include "libc/nt/synchronization.h"
#include "libc/sysv/consts/sicode.h"
#include "libc/sysv/errfuns.h"
#include "libc/thread/posixthread.internal.h"
#ifdef __x86_64__
// returns 0 on timeout or spurious wakeup
// raises EINTR if a signal delivery interrupted wait operation
// raises ECANCELED if this POSIX thread was canceled in masked mode
static textwindows int _park_thread(uint32_t msdelay, sigset_t waitmask,
textwindows static int _park_thread(uint32_t msdelay, sigset_t waitmask,
bool restartable) {
int sig, handler_was_called;
if (_check_cancel() == -1)
if (__sigcheck(waitmask, restartable) == -1)
return -1;
if (_weaken(__sig_get) && (sig = _weaken(__sig_get)(waitmask)))
goto HandleSignal;
int expect = 0;
atomic_int futex = 0;
struct PosixThread *pt = _pthread_self();
@ -43,17 +37,8 @@ static textwindows int _park_thread(uint32_t msdelay, sigset_t waitmask,
atomic_store_explicit(&pt->pt_blocker, &futex, memory_order_release);
bool32 ok = WaitOnAddress(&futex, &expect, sizeof(int), msdelay);
atomic_store_explicit(&pt->pt_blocker, 0, memory_order_release);
if (ok && _weaken(__sig_get) && (sig = _weaken(__sig_get)(waitmask))) {
HandleSignal:
handler_was_called = _weaken(__sig_relay)(sig, SI_KERNEL, waitmask);
if (_check_cancel() == -1)
return -1;
if (handler_was_called & SIG_HANDLED_NO_RESTART)
return eintr();
if (handler_was_called & SIG_HANDLED_SA_RESTART)
if (!restartable)
return eintr();
}
if (ok && __sigcheck(waitmask, restartable) == -1)
return -1;
return 0;
}