getaddrinfo can hang for many seconds when the system stub resolver
misbehaves; running it inline on the event loop froze every other
request, IPC, and curl socket event for the duration.
New PendingSystemResolution coalesces concurrent lookups for the same
name, dispatches the call to a Threading::ThreadPool worker, and
deferred-invokes the result back to the originating event loop. Each
caller of lookup() gets its own Core::Promise so concurrent
when_resolved/when_rejected handlers can't clobber each other; the
pending state fans out to every joined caller on completion.
Workers issue A and AAAA in parallel on separate sockets to sidestep
the systemd-resolved AAAA-drop bug, and resolve the user's promise
after the first side returns records (with a 50 ms RFC 8305 grace
window for the other side).
Adds Core::Socket::AddressFamily and an optional parameter to
resolve_host so workers can request A or AAAA specifically.
SocketAddressWindows.h contains a bunch of copy-pasted Windows
definitions. This started causing ad-nauseam redefinition errors when
implementing the HTTP disk cache for Windows.
Instead, let's forward-declare the types we can in SocketAddress.h and
only define the couple of constants that we need. We can then assert at
compile-time that we defined them correctly.
Our Core::System::is_socket() helper is not very robust, as it was
incorrectly marking m_fd as a non-socket fd. This meant we were trying
to call CLoseHandle() on a socket which fails. We can just call
closesocket() directly given we are in an explicit socket-only context.
In SocketWindows, the return value for the ioctl call was not
initialized to zero. This was causing test_udp in TesDNSResolver
to fail as UDPSocket::read_some() was incorrectly failing with
WSAEMSGSIZE due the result of pending_bytes being some
unspecified default value for an uninitialized unsigned long
It fixes a bug in which ImageDecoder and RequestServer
do not exit because their connections don't close.
This makes the shutdown behavior match the Linux version,
which receives FD_READ | FD_HANGUP on socket close, and
TransportSocket::read_as_much_as_possible_without_blocking calls
schedule_shutdown when read from a socket returns 0 bytes.
On Windows, we have to explicitly call WIN32 shutdown to receive
notification FD_CLOSE.
Windows flavor of non-blocking IO, overlapped IO, differs from that on
Linux. On Windows, the OS handles writing to overlapped buffer, while
on Linux user must do it manually.
Additionally, we can only have overlapped sockets because it is the
requirement to be able to wait on them - WSAEventSelect automatically
sets socket to nonblocking mode.
So we end up emulating Linux-nonblocking sockets with
Windows-nonblocking sockets.
Pending IO state (ERROR_IO_PENDING) must not escape read/write
functions. If that happens, all synchronization like WSAPoll and
WaitForMultipleObjects stops working (WaitForMultipleObjects stops
working because with overlapped IO you are supposed to wait on an event
in OVERLAPPED structure, while we are waiting on WSA Event, see
EventLoopImplementationWindows.cpp).