mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-03 11:12:27 +00:00
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:
parent
5469202ea8
commit
e142124730
25 changed files with 556 additions and 277 deletions
26
libc/calls/clock_gettime_monotonic_nt.c
Normal file
26
libc/calls/clock_gettime_monotonic_nt.c
Normal 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);
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue