Repository navigation
fix(libSceNet): report EAGAIN when a stream receive times out on Windows - #9106
Merged
oneandonlydean merged 1 commit intoOct 22, 2026
Merged
oneandonlydean merged 1 commit into
oneandonlydean merged 1 commit into
Conversation
FreeBSD 11.4's soreceive_generic waits in sbwait (sys/kern/uipc_socket.c, uipc_sockbuf.c), whose msleep_sbt on so_rcv.sb_timeo returns EWOULDBLOCK (35) for every socket type when SO_RCVTIMEO expires. On Windows the host socket is non-blocking and native_transfer enforces the timeout itself, but it reported WSAETIMEDOUT, which only datagram receives turned into EAGAIN; a stream receive failed with ETIMEDOUT (60). A receive that reaches the stored timeout now reports WSAEWOULDBLOCK, so every receive returns EAGAIN, and a host WSAETIMEDOUT still maps to ETIMEDOUT.
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
Contributor
|
Windows run of 3509bb5 merged onto Built |
Merged
12 tasks done
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.
What
On Windows,
sceNetRecv,sceNetRecvfromandsceNetRecvmsgon a stream socket whoseSO_RCVTIMEOexpired failed withETIMEDOUT(0x8041013C, errno 60). FreeBSD 11.4'ssoreceive_genericwaits insbwait(sys/kern/uipc_socket.c,sys/kern/uipc_sockbuf.c), and itsmsleep_sbtonso_rcv.sb_timeoreturnsEWOULDBLOCK(35) for every socket type. Linux already givesEAGAINhere.Since #8653 the Windows host socket is always non-blocking and
native_transferenforces the stored timeout itself, but on expiry it setWSAETIMEDOUT.receive_errorturned that intoEAGAINonly for datagram sockets. #4092 left streams out because Winsock leaves a connection in an indeterminate state after a timeout on a blocking socket. That no longer applies: the host socket is non-blocking, so the timeout never reaches Winsock.native_transfernow setsWSAEWOULDBLOCKwhen a receive reaches its timeout, so every receive reportsEAGAIN, andreceive_erroris removed. AWSAETIMEDOUTfrom the host, such as a dropped connection, still maps toETIMEDOUT, as FreeBSD returns it fromso_error. Send timeouts are unchanged. libkernel's ownrecvalready returns 35 when its receive timeout expires. The sentence about this gap is cut from thesceNetSetsockoptentry indocs/dev/debt/libSceNet.md.Test changes:
guest_sce_net(CheckStreamReceiveTimeout): a connected TCP socket with a 50 msSO_RCVTIMEOand no data failssceNetRecv,sceNetRecvfromandsceNetRecvmsgwithEAGAINafter at least 40 ms. The peer then sends, and a receive on the same socket returns the data. Sending in the other direction still works.Tested
Windows 11, WinLibs MinGW-w64 GCC 15.2.0 r7, CMake + Ninja, Release,
-DBUILD_TESTING=ON, onmaind099bc6.guest_sce_netwith the new check fails (exit 0xc0000409). A temporary probe showed the stream receive returning 0x8041013C with errno 60. With this PR it passes.net_*,guest_datagram_*,guest_refused_connect*,guest_socket_host_write_*,guest_sce_netandguest_ssl_transport_*: 33 of 33 pass when run serially.python tools/check_conventions.py --base origin/mainreports no errors.main745b394 on Windows 11 (same toolchain):guest_sce_netpasses on two repeats (comment below).recvthat reachesSO_RCVTIMEOalready fails withEAGAIN, so the new check should pass there unchanged.Overlap:
tools/pr_overlap.pyreports no overlap with open pull requests. #8686 changes zero-length stream receives in the same file, not timeouts.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)