Skip to content

feat(libkernel): apply SO_RCVTIMEO and SO_SNDTIMEO on a guest socket - #5617

Merged
adriadam10 merged 2 commits into
boykopovar:mainfrom
Dripl1x:feat/socket-timeouts
Oct 15, 2026
Merged

adriadam10 merged 2 commits into
boykopovar:mainfrom
Dripl1x:feat/socket-timeouts

Conversation

@Dripl1x

@Dripl1x Dripl1x commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

What

The first commit of this branch is #5565 as ported to main (7e79f36ed), unchanged. This PR is the second commit. It adds two options to the same structure: the handling is in Socket/src/SocketOptions.cpp, and the values are in SocketOptionState under modeMutex.

setsockopt and getsockopt on a socket from socket() fail SO_SNDTIMEO (0x1005) and SO_RCVTIMEO (0x1006) with ENOPROTOOPT, and a blocking receive never times out. Now:

  • The value is checked and kept as FreeBSD 11.4's sosetopt does. It is a 16-byte timeval; a negative field or 1000000 microseconds or more fails with EDOM, and more than INT32_MAX seconds becomes the longest wait. It is stored in SocketOptionState::sendTimeout and receiveTimeout and read back through the same 32.32 fixed-point conversion (tvtosbt, sbttotv), so half a second reads back as 499999 microseconds and one microsecond as 0. A short or null value fails with EINVAL, as for the other options there.
  • send, recv, sendto, recvfrom and recvmsg on a blocking socket wait that long for the host to report the socket readable or writable, then fail with EWOULDBLOCK. The wait reads the timeout and the non-blocking flag together under modeMutex. A call with MSG_DONTWAIT, which main now accepts on Linux, does not wait, as FreeBSD's soreceive and sosend do not sleep for it. The other calls reach these five: read and readv go through recv, write and writev through send, and sendmsg through sendto. A non-blocking socket and a timeout of 0 behave as before.
  • An accepted socket takes both timeouts from its listener, as sonewconn copies them, in the same locked block that copies the other options.
  • Recorded in the SocketOptions.cpp entry of docs/dev/debt/libkernel.md:
    • The wait covers the first transfer only. Once the socket is writable the host send runs without a limit, where FreeBSD stops a send that cannot finish and returns the bytes sent so far.
    • A receive whose data another thread takes between the wait and the host call blocks again.
    • sendfile ignores the send timeout.
    • The host wait has millisecond steps.

Titles that ask for them:

  • PokeMMO Prospero (PPSA98001) sets both. A temporary trace on main 90d0cb481, not part of this PR, shows setsockopt(SOL_SOCKET, SO_RCVTIMEO) and SO_SNDTIMEO with 2 s failing with ENOPROTOOPT (42). It happens three times while the title checks for a local FTP server. The title does not stop there: each check ends after about 2 s with no answer.
  • RommPS (PPSA76677) sets both on its HTTP client socket to bound a request. SwanStationPS5 (PPSA98510) sets two seconds on both. On main both calls fail, and the sockets wait without a limit. This is read from their sources; neither title was run.
  • A static survey of the 63 executables of ps5-homebrew-catalog (not run): SO_RCVTIMEO is set by 27 titles and SO_SNDTIMEO by 24, and each is read by 19. The option was recovered at 840 of 2661 setsockopt call sites, so these are lower bounds. The lists and the method are in this comment.

No title is known to stop on these options on main.

Related: #5565 is the first commit of this branch and the base of this change. Once it lands, this PR is rebased to carry only its own commit.

Tested

Windows 11, Ryzen 7 5800H, WinLibs MinGW-w64 GCC 15.2.0 r7; Ubuntu 26.04 under WSL, GCC 15.2.0. Release, BUILD_TESTING=ON, root configuration with FFMPEG_PREBUILT_DIR pointed at an already unpacked package. Head 17ded56f1, on #5565 7e79f36ed, on main 4c1de0c0c.

  • The new test guest_socket_timeouts covers values and read-back with FreeBSD's rounding, EDOM, short arguments and a truncated read. It checks EWOULDBLOCK from recv, recvfrom, recvmsg and read on a datagram socket and from recv on a stream socket. On Linux it checks that recv, recvfrom and recvmsg with MSG_DONTWAIT fail with EWOULDBLOCK at once under a 60 s timeout; without the check for the flag the test runs into its 20 s limit. It also covers a datagram received while the timeout is set, inheritance by an accepted socket, and a stream send that stops with EWOULDBLOCK once the peer's buffers are full. Its only clock check is a lower bound: a 60 ms wait does not end before 59 ms.
  • Negative control: with SocketOptions.hpp, SocketOptions.cpp and Udp.cpp of the first commit and the new test, guest_socket_timeouts fails on both systems with socket timeout check failed at line 93, errno 42.
  • Windows: the new test passes 20 of 20 repeated runs. Of the thirteen socket tests twelve pass. guest_udp times out after 20 s, and does so on main too: a VPN on this machine drops IPv6 loopback traffic, so a datagram to [::1] never arrives, even between two plain host sockets.
  • Linux: the thirteen socket tests pass in 1.34 s, guest_udp included.
  • The conventions checker, including the title and description, and git diff --check pass.

Not tested: any title, a console, macOS, the full test suite. Full PR builds need a collaborator's manual Build run.

Checklist

🤖 Generated with Claude Code

@Dripl1x

Dripl1x commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

Evidence for head 8b4309fbf. Local paths are replaced with <build>.

Which catalog titles ask for the two options

Call Titles Call sites Titles
setsockopt(SOL_SOCKET, SO_RCVTIMEO) 27 80 PPSA17641 SymphonyStation5, PPSA19111 XashPS5, PPSA28319 Middle Ages Ping Pong, PPSA69421 SuperTuxKart, PPSA74126 Stremio Plus, PPSA76677 RommPS, PPSA85300 VLC, PPSA97510 PSXS5, PPSA98510 SwanStationPS5, PPSA99000 ProsperoStore, PPSA99001 ProsperoRadio, PPSA99003 ProsperoTV, PPSA99004 ProsperoAI, PPSA99008 ProsperoEden, PPSA99039 EVO Player, PPSA99141 Mortalfin, PPSA99169 RetroArch, PPSA99177 PS5VR, PPSA99288 Nuvio Max'd, PPSA99420 PS5MC, PPSA99505 Jelly5, PPSA99515 Emby5, PPSA99764 Porpoise, PPSA99773 PShare, PPSA99810 PSBox Cloud Gaming, PPSA99930 Forwarder Manager, PPSA99997 Nuvio PS5
setsockopt(SOL_SOCKET, SO_SNDTIMEO) 24 32 PPSA17641 SymphonyStation5, PPSA69421 SuperTuxKart, PPSA74126 Stremio Plus, PPSA76677 RommPS, PPSA85300 VLC, PPSA97510 PSXS5, PPSA98510 SwanStationPS5, PPSA99000 ProsperoStore, PPSA99001 ProsperoRadio, PPSA99003 ProsperoTV, PPSA99004 ProsperoAI, PPSA99008 ProsperoEden, PPSA99039 EVO Player, PPSA99141 Mortalfin, PPSA99177 PS5VR, PPSA99203 PS5SX2, PPSA99288 Nuvio Max'd, PPSA99420 PS5MC, PPSA99505 Jelly5, PPSA99515 Emby5, PPSA99773 PShare, PPSA99810 PSBox Cloud Gaming, PPSA99930 Forwarder Manager, PPSA99997 Nuvio PS5
getsockopt(SOL_SOCKET, SO_RCVTIMEO) 19 38 PPSA17641 SymphonyStation5, PPSA69421 SuperTuxKart, PPSA74126 Stremio Plus, PPSA97510 PSXS5, PPSA98510 SwanStationPS5, PPSA99000 ProsperoStore, PPSA99001 ProsperoRadio, PPSA99003 ProsperoTV, PPSA99004 ProsperoAI, PPSA99039 EVO Player, PPSA99141 Mortalfin, PPSA99177 PS5VR, PPSA99288 Nuvio Max'd, PPSA99420 PS5MC, PPSA99505 Jelly5, PPSA99515 Emby5, PPSA99773 PShare, PPSA99930 Forwarder Manager, PPSA99997 Nuvio PS5
getsockopt(SOL_SOCKET, SO_SNDTIMEO) 19 19 PPSA17641 SymphonyStation5, PPSA69421 SuperTuxKart, PPSA74126 Stremio Plus, PPSA97510 PSXS5, PPSA98510 SwanStationPS5, PPSA99000 ProsperoStore, PPSA99001 ProsperoRadio, PPSA99003 ProsperoTV, PPSA99004 ProsperoAI, PPSA99039 EVO Player, PPSA99141 Mortalfin, PPSA99177 PS5VR, PPSA99288 Nuvio Max'd, PPSA99420 PS5MC, PPSA99505 Jelly5, PPSA99515 Emby5, PPSA99773 PShare, PPSA99930 Forwarder Manager, PPSA99997 Nuvio PS5

Method: as in #5565. The 65 release archives listed in the catalog were downloaded (SHA-256 equal to the catalog records) and the 63 eboot.bin unwrapped; nothing was run. The level and option were read from the instructions before each call site and recovered at 840 of 2661 setsockopt call sites, so the counts are lower bounds.

Tests

Windows: guest_socket_timeouts, 20 repeated runs
Test project <build>
    Test #956: guest_socket_timeouts ............   Passed    0.40 sec
    Test #956: guest_socket_timeouts ............   Passed    0.39 sec
    Test #956: guest_socket_timeouts ............   Passed    0.39 sec
    Test #956: guest_socket_timeouts ............   Passed    0.38 sec
    Test #956: guest_socket_timeouts ............   Passed    0.39 sec
    Test #956: guest_socket_timeouts ............   Passed    0.38 sec
    Test #956: guest_socket_timeouts ............   Passed    0.39 sec
    Test #956: guest_socket_timeouts ............   Passed    0.38 sec
    Test #956: guest_socket_timeouts ............   Passed    0.38 sec
    Test #956: guest_socket_timeouts ............   Passed    0.39 sec
    Test #956: guest_socket_timeouts ............   Passed    0.39 sec
    Test #956: guest_socket_timeouts ............   Passed    0.38 sec
    Test #956: guest_socket_timeouts ............   Passed    0.38 sec
    Test #956: guest_socket_timeouts ............   Passed    0.38 sec
    Test #956: guest_socket_timeouts ............   Passed    0.38 sec
    Test #956: guest_socket_timeouts ............   Passed    0.38 sec
    Test #956: guest_socket_timeouts ............   Passed    0.38 sec
    Test #956: guest_socket_timeouts ............   Passed    0.39 sec
    Test #956: guest_socket_timeouts ............   Passed    0.39 sec
1/1 Test #956: guest_socket_timeouts ............   Passed    0.41 sec
100% tests passed, 0 tests failed out of 1
Total Test time (real) =   7.88 sec
Windows: the ten socket tests (guest_udp times out on this machine on main too)
Test project <build>
 1/10 Test #948: guest_socket_error ...............   Passed    0.05 sec
 2/10 Test #949: guest_udp ........................***Timeout  20.02 sec
 3/10 Test #950: guest_socket_read_write ..........   Passed    0.06 sec
 4/10 Test #951: guest_poll .......................   Passed    0.26 sec
 5/10 Test #952: guest_tcp ........................   Passed    0.06 sec
 6/10 Test #953: guest_socket_pair ................   Passed    0.06 sec
 7/10 Test #955: guest_socket_stream_options ......   Passed    0.03 sec
 8/10 Test #956: guest_socket_timeouts ............   Passed    0.39 sec
 9/10 Test #958: guest_socket_descriptors .........   Passed    0.06 sec
10/10 Test #959: guest_socket_events ..............   Passed    0.21 sec
90% tests passed, 1 tests failed out of 10
Total Test time (real) =  21.33 sec
	949 - guest_udp (Timeout)
Windows control: Udp.cpp of the first commit, new test
Test project <build>
1/1 Test #956: guest_socket_timeouts ............Exit code 0xc0000409***Exception:   0.26 sec
socket timeout check failed at line 93, errno 42
0% tests passed, 1 tests failed out of 1
Total Test time (real) =   0.35 sec
Linux: the eleven socket tests
Test project <build>
 1/11 Test #921: guest_socket_error ...............   Passed    0.00 sec
 2/11 Test #922: guest_udp ........................   Passed    0.01 sec
 3/11 Test #923: guest_socket_read_write ..........   Passed    0.05 sec
 4/11 Test #924: guest_poll .......................   Passed    0.18 sec
 5/11 Test #925: guest_select .....................   Passed    0.31 sec
 6/11 Test #926: guest_tcp ........................   Passed    0.01 sec
 7/11 Test #927: guest_socket_pair ................   Passed    0.01 sec
 8/11 Test #929: guest_socket_stream_options ......   Passed    0.01 sec
 9/11 Test #930: guest_socket_timeouts ............   Passed    0.45 sec
10/11 Test #932: guest_socket_descriptors .........   Passed    0.01 sec
11/11 Test #933: guest_socket_events ..............   Passed    0.15 sec
100% tests passed, 0 tests failed out of 11
Total Test time (real) =   1.23 sec
Linux control: Udp.cpp of the first commit, new test
Test project <build>
1/1 Test #930: guest_socket_timeouts ............Subprocess aborted***Exception:   0.01 sec
socket timeout check failed at line 93, errno 42
0% tests passed, 1 tests failed out of 1
Total Test time (real) =   0.08 sec

AI-assisted (Claude Code).

@github-actions github-actions Bot added libkernel build docs needs rebase Conflicts with main, rebase needed labels Oct 14, 2026
@adriadam10 adriadam10 self-assigned this Oct 14, 2026

@adriadam10 adriadam10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is stacked on #5565, which still needs to be ported to main: #4796 is merged, so setsockopt/getsockopt now delegate to GuestSockets::SetSocketLevelOption/GetSocketLevelOption in Socket/src/SocketOptions.cpp, with per-socket state in Socket::options under modeMutex. The branch conflicts with main in Udp.cpp for that reason.

  • Udp.cpp OwnOption/SetOwnOption/GetOwnOption is a second dispatcher in front of that code. Please put SO_SNDTIMEO/SO_RCVTIMEO into SocketOptions.cpp and keep the timeouts in SocketOptionState rather than two separate atomics on Socket.
  • Rebase after #5565 is ported so this PR carries only its own commit. Keep the WaitForTransfer calls in send/recv/sendto/recvfrom/recvmsg (and read/write/sendmsg as the description says; I only see the five in the diff, please check the others go through them).
  • The description names RommPS and SwanStationPS5 from their sources only. If one of them stops on this on current main, add the title ID and the log line, as requested for the other socket PRs.

Happy to re-review once it is rebased on the ported base.

@Dripl1x

Dripl1x commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

@adriadam10 done. The branch is now the ported #5565 (1e4783573) plus this PR's own commit, 514d0033e:

  • SO_SNDTIMEO and SO_RCVTIMEO are handled in SetSocketLevelOption and GetSocketLevelOption in SocketOptions.cpp. The values are SocketOptionState::sendTimeout and receiveTimeout. The two atomics on Socket and the dispatcher in Udp.cpp are gone.
  • WaitForTransfer reads the timeout and the non-blocking flag together under modeMutex, then waits without holding it. accept copies both timeouts in the locked block that copies the other options.
  • read, write and sendmsg do go through the five calls with the wait. GuestSockets::Read and Readv call recv_nid_postfix, Write and Writev call send_nid_postfix, and sendmsg_nid_postfix calls sendto_nid_postfix. The test covers read directly; the description now says which call each one goes through.
  • Titles: no title is known to stop on these options on main. The one I saw call them at run time is PokeMMO Prospero (PPSA98001). A temporary trace on main 90d0cb481 shows SO_RCVTIMEO and SO_SNDTIMEO with 2 s failing with ENOPROTOOPT three times during its local FTP check. Each check still ends after about 2 s with no answer, so nothing visible changes there. RommPS and SwanStationPS5 remain read from their sources. The description says so.

Results at 514d0033e:

  • Windows: guest_socket_timeouts passes 20 of 20 repeated runs, and 12 of the 13 socket tests pass. guest_udp times out on main too, because the VPN on this machine drops IPv6 loopback traffic.
  • Linux: all 13 pass in 1.31 s.
  • Control: with the production files of 1e4783573, guest_socket_timeouts fails on both systems at line 92, errno 42.

AI-assisted (Claude Code).

@Dripl1x
Dripl1x requested a review from adriadam10 October 14, 2026 15:43
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 14, 2026
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 14, 2026
Dripl1x and others added 2 commits October 14, 2026 22:17
…est socket

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Dripl1x
Dripl1x force-pushed the feat/socket-timeouts branch from 514d003 to 17ded56 Compare October 14, 2026 19:33
@Dripl1x

Dripl1x commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

Rebased both branches onto main 4c1de0c0c after #5020 and #4676 landed.

Results: Linux, all 13 socket tests pass on this head and all 12 on #5565's. Windows, 12 of 13 and 11 of 12 (guest_udp only, the VPN on this machine). guest_socket_timeouts, guest_socket_stream_options and guest_socket_options pass 20 repeated runs on Windows. The controls still fail: guest_socket_timeouts against #5565's code at line 93, errno 42, and the option tests against main's code at line 91, errno 42.

AI-assisted (Claude Code).

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

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.

Pull request Shared files not compared
PR 3891 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4156 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4396 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4397 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4422 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4423 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4424 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4520 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4521 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4522 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4523 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4566 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4599 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4718 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4740 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4749 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4760 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4813 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 4972 core/libs/prx/libkernel/CMakeLists.txt
PR 5021 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 5835 core/libs/prx/libkernel/CMakeLists.txt
docs/dev/debt/libkernel.md
PR 6044 core/libs/prx/libkernel/CMakeLists.txt
PR 6107 core/libs/prx/libkernel/CMakeLists.txt
PR 6222 core/libs/prx/libkernel/CMakeLists.txt
core/libs/prx/libkernel/Socket/src/Udp.cpp
docs/dev/debt/libkernel.md
PR 6226 core/libs/prx/libkernel/CMakeLists.txt

@adriadam10 adriadam10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-checked against the points of the previous review: the timeouts now live in SocketOptions.cpp with the values in SocketOptionState under modeMutex, the branch is one commit on current main, and read/readv go through recv, write/writev through send, sendmsg through sendto. Built and ran the libs/libkernel ctest scope (174 tests, all pass), guest_socket_timeouts included, and it fails with the non-test changes reverted. Merging once the Windows build is green.

@screamm

screamm commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Cross-validation on Windows 11 Pro 26220, NVIDIA RTX 4070 (596.21), MinGW GCC 15.2, PR head 17ded56f1 merged on main b08db6a09:

#5565 is already on main (1036905b5), so the merge adds only this PR's commit. Catalog releases, app0/eboot.bin staged, relinker --windows --registry unused-filter=0, display on, 90 s per run. The host was busy with other builds, so frame counts follow load. To see the calls I wrapped libkernel setsockopt/getsockopt in a local stderr trace (not part of the PR).

RommPS (PPSA76677)

  • main (run, traced run): RommPS | FPS: 59.46 (4794), RommPS | FPS: 46.13 (4677).
  • This PR: RommPS | FPS: 49.26 (3675), RommPS | FPS: 55.76 (4277).
  • All running at 90 s. The trace has no setsockopt call at all: http_request only runs when the title talks to RomM Sync.

SwanStationPS5 (PPSA98510)

  • main: SwanStationPS5 | FPS: 33.23 (3316), FPS: 65.75 (7143).
  • This PR: FPS: 116.35 (8461), FPS: 36.17 (4232).
  • All running at 90 s, with no setsockopt call. request_over_tcp only runs when /data is not listable; here the log has storage probe before unlock: sandboxed read no, write no, list ok and storage: unlocked.

Other titles

  • Stremio Plus (PPSA74126) and Nuvio Max'd (PPSA99288) were traced with this PR as extra probes. Their curl sockets set TCP_NODELAY, SO_NOSIGPIPE and 0x1200 (all = 0), but never 0x1005 or 0x1006.
  • The feat(libkernel): answer TCP_NODELAY, SO_NOSIGPIPE and SO_NBIO on a guest socket #5565 titles still render with this PR, none with a stop line: ProsperoRadio FPS: 46.19 (4531), VITA5 FPS: 59.68 (3570), ProsperoStore FPS: 12.43 (1106).
  • So I have no title that reaches the new options; PokeMMO (PPSA98001) is not available here.

Tests

  • guest_socket_timeouts, guest_socket_options and guest_socket_stream_options pass 3/3 (--repeat until-fail:3).
  • Negative control (SocketOptions.hpp, SocketOptions.cpp and Udp.cpp from b08db6a09, new test kept): socket timeout check failed at line 93, errno 42.

Suite. ctest -j8 --timeout 120 -E '^agc_driver_|^video_out_flip': 825 tests, 16 failed under host load. 14 of the 16 pass when rerun serially. prx_thread_local_destructors reports the libSceAgcDriver traceDrawKeyLookup thread_local, which #6349 fixes after b08db6a09. hardware_oracle_compare hits its 20 s limit under load.

Conventions. tools/check_conventions.py with title and description passes. git diff --check is clean.

Review. The checks and conversions match the pinned FreeBSD 11.4 sources: EDOM and SBT_MAX from sosetopt, tvtosbt/sbttotv exactly (hence 499999 µs, and (0x7fffffff, 999999) for SBT_MAX), sogetopt read-back, and sonewconn copying both timeouts. The known limits are in the debt entry.

One difference on Windows. On a TCP socket that was never connected, FreeBSD's sosend_generic and soreceive_generic return ENOTCONN before any wait (uipc_socket.c L1271-1291 and L1567-1573). Without a timeout this PR does too: send gives errno 57 at once. With a 300 ms SO_SNDTIMEO/SO_RCVTIMEO, send and recv wait the full 300 ms and fail with EWOULDBLOCK (35). I measured this with a temporary probe appended to the test: send no timeout=-1 errno 57 (0 ms); send 300 ms timeout=-1 errno 35 (301 ms); recv 300 ms timeout=-1 errno 35 (300 ms). The cause is that WSAPoll reports nothing on an unconnected TCP socket until the timeout; a host probe got 0 and revents 0 after 2 s for both POLLWRNORM and POLLRDNORM. Skipping the wait when the stream socket is not connected (for example when getpeername gives WSAENOTCONN) would let the host call report ENOTCONN. Otherwise it could go into the debt entry. I did not check Linux.

Written with Claude Code assistance.

@adriadam10
adriadam10 merged commit 9490a6d into boykopovar:main Oct 15, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants