Rewrite Windows connect()

Our old code wasn't working with projects like Qt that call connect() in
O_NONBLOCK mode multiple times. This change overhauls connect() to use a
simpler WSAConnect() API and follows the same pattern as cosmo accept().
This change also reduces the binary footprint of read(), which no longer
needs to depend on our enormous clock_gettime() function.
This commit is contained in:
Justine Tunney 2024-09-12 23:01:20 -07:00
parent 5469202ea8
commit e142124730
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
25 changed files with 556 additions and 277 deletions

View file

@ -0,0 +1,26 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2024 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/timespec.internal.h"
#include "libc/nt/time.h"
textwindows struct timespec sys_clock_gettime_monotonic_nt(void) {
uint64_t hectons;
QueryUnbiasedInterruptTimePrecise(&hectons);
return timespec_fromnanos(hectons * 100);
}

View file

@ -21,6 +21,7 @@
#include "libc/calls/struct/sigset.h"
#include "libc/calls/struct/sigset.internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timespec.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/fds.h"
@ -58,14 +59,8 @@
#define POLLPRI_ 0x0400 // MSDN unsupported
// </sync libc/sysv/consts.sh>
textwindows dontinline static struct timespec sys_poll_nt_now(void) {
uint64_t hectons;
QueryUnbiasedInterruptTimePrecise(&hectons);
return timespec_fromnanos(hectons * 100);
}
textwindows static uint32_t sys_poll_nt_waitms(struct timespec deadline) {
struct timespec now = sys_poll_nt_now();
struct timespec now = sys_clock_gettime_monotonic_nt();
if (timespec_cmp(now, deadline) < 0) {
struct timespec remain = timespec_sub(deadline, now);
int64_t millis = timespec_tomillis(remain);
@ -340,7 +335,7 @@ textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint32_t *ms,
int rc;
struct timespec now, timeout, deadline;
BLOCK_SIGNALS;
now = ms ? sys_poll_nt_now() : timespec_zero;
now = ms ? sys_clock_gettime_monotonic_nt() : timespec_zero;
timeout = ms ? timespec_frommillis(*ms) : timespec_max;
deadline = timespec_add(now, timeout);
rc = sys_poll_nt_impl(fds, nfds, deadline, sigmask ? *sigmask : _SigMask);

View file

@ -24,6 +24,7 @@
#include "libc/calls/struct/iovec.h"
#include "libc/calls/struct/sigset.internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timespec.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/cosmo.h"
#include "libc/ctype.h"
@ -837,7 +838,8 @@ textwindows static int CountConsoleInputBytesBlockingImpl(uint32_t ms,
uint32_t wi;
struct timespec now, deadline;
InitConsole();
deadline = timespec_add(timespec_mono(), timespec_frommillis(ms));
deadline =
timespec_add(sys_clock_gettime_monotonic_nt(), timespec_frommillis(ms));
RestartOperation:
if (_check_cancel() == -1)
return -1;
@ -870,7 +872,7 @@ RestartOperation:
// 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 = timespec_mono();
now = sys_clock_gettime_monotonic_nt();
if (timespec_cmp(now, deadline) >= 0)
return etimedout();
ms = timespec_tomillis(timespec_sub(deadline, now));

View file

@ -25,6 +25,7 @@ int sys_sem_timedwait(int64_t, const struct timespec *);
int sys_utimensat(int, const char *, const struct timespec[2], int);
int sys_utimensat_nt(int, const char *, const struct timespec[2], int);
int sys_utimensat_old(int, const char *, const struct timespec[2], int);
struct timespec sys_clock_gettime_monotonic_nt(void);
const char *_DescribeTimespec(char[45], int, const struct timespec *);
#define DescribeTimespec(rc, ts) _DescribeTimespec(alloca(45), rc, ts)