Skip to content

Emulate socketPair with TCP over loopback on Windows - #630

Merged
kazu-yamamoto merged 2 commits into
haskell:masterfrom
kazu-yamamoto:socketpair-tcp
Nov 4, 2026
Merged

kazu-yamamoto merged 2 commits into
haskell:masterfrom
kazu-yamamoto:socketpair-tcp

Conversation

@kazu-yamamoto

Copy link
Copy Markdown
Collaborator

On Windows, socketPair emulates socketpair() with an AF_UNIX listener and connection. Windows' AF_UNIX misses a peer's closesocket which races a recv entering its wait: the recv never returns, though a second recv on the same socket gets EOF at once. It happens in plain C too, with blocking, overlapped and IOCP receives alike (a few to a few dozen times in 2000 rounds on windows-latest), and never over TCP. The non-threaded RTS hits it in a Haskell program; it was found through simple-sendfile's test suite.

This PR builds the pair over TCP on 127.0.0.1 instead:

  • The listener is bound to an ephemeral loopback port, and the connection accepted is checked to be ours, since another process may connect to the port first.
  • Both ends get TCP_NODELAY, as a stream pair should not delay small writes.
  • The temporary file the AF_UNIX pair left behind goes, and so does the temporary dependency on Windows.

The pair's family is now AF_INET on Windows; the arguments were already ignored there.

The socketPair tests now run on Windows too, with a new one where the peer closes while the other end waits in recv. macOS, and Windows with GHC 9.8.2 and 9.12 (MIO and WinIO), pass.

🤖 Generated with Claude Code

kazu-yamamoto and others added 2 commits November 4, 2026 11:55
On Windows, AF_UNIX misses a peer's close which races a recv entering
its wait, and the recv waits for ever.  This happens with blocking,
overlapped and IOCP receives alike, but never over TCP.  The temporary
file the AF_UNIX pair left behind goes too.

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 to kazu-yamamoto/network that referenced this pull request Nov 4, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kazu-yamamoto
kazu-yamamoto merged commit 1f6aa85 into haskell:master Nov 4, 2026
@kazu-yamamoto
kazu-yamamoto deleted the socketpair-tcp branch November 4, 2026 04:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant