Repository navigation
WinIO the POSIX way: non-blocking sockets, readiness-based give-ups - #643
Merged
Merged
Conversation
So that Network.Socket.Internal can wait through it too, and add a blocking afdWait beside the STM one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
As on POSIX, a call which would block says WSAEWOULDBLOCK, and the throwSocketErrorWait* guards wait for readiness and retry. accept and connect take the POSIX path under WinIO: no thread blocks in a foreign call, and connect reads SO_ERROR once the socket is writable. Overlapped operations are not affected by the mode. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GHC's withException raised them with its own error type; going through throwSocketErrorCode keeps the Winsock code in ioe_errno with the IOErrorType it stands for. A stream reset was taken for the end of the stream; it is raised, as on POSIX and under MIO. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Under WinIO the give-up API waits for readiness through the AFD poll and runs the operation once the socket is ready, as on POSIX, rather than starting it in a thread of its own and cancelling it. Giving up ends the wait alone: nothing received is lost, and other threads' operations on the socket are left alone. connectWith connects without blocking. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kazu-yamamoto
added a commit
that referenced
this pull request
Nov 15, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Nov 15, 2026
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The next item of #642: under WinIO, sockets behave as on POSIX, waiting for readiness through the AFD poll of #641.
socketandacceptput them in non-blocking mode (FIONBIO), as on POSIX. Overlapped operations are not affected by the mode; a plain call which would block saysWSAEWOULDBLOCK, and thethrowSocketErrorWait*guards wait for readiness and retry, as they do withthreadWaitReadon POSIX.acceptandconnecttake the POSIX path. No thread blocks in a foreign call any more;connectreadsSO_ERRORonce the socket is writable.withReadyas POSIX, instead of starting it in a thread of its own and cancelling it withCancelIoEx. Giving up ends the wait alone, so nothing received is lost and other threads' operations on the socket are left alone. A socket which is ready already is found withWSAPolland a zero timeout, aspollis used on POSIX.connectWithconnects without blocking.throwSocketErrorCode, so they carry the Winsock code inioe_errnowith theIOErrorTypeit stands for (Give Winsock errors the IOErrorType of their errno #632), instead of the type GHC'swithExceptiongives. A stream reset (WSAECONNRESET) was taken for the end of the stream; it is raised, as on POSIX and with No IO Manager.Network.Socket.Win32.AfdPollholds the poll, so thatNetwork.Socket.Internalcan use it too.The No IO Manager code is unchanged; removing it is the next item.
Tested on Windows 11 with GHC 9.12.4.20260713: 123 examples, 0 failures under WinIO and with No IO Manager (7 pending), and with GHC 9.8.2. macOS: 127 examples, 0 failures. Three tests, "an ICMP unreachable from a send of one's own", come and go on that machine: master and this branch both failed them 10 times out of 10 in one series and passed them in another, so they depend on the state of Windows (it seems to stop sending ICMP errors for a while after heavy traffic), not on this change. CI's Windows jobs compile WinIO out, so this is tested locally only.
🤖 Generated with Claude Code