Repository navigation
fix(libSceNetCtl): keep the callback argument and deliver the state from sceNetCtlCheckCallback - #6138
Open
fdfawef324 wants to merge 1 commit into
Open
fix(libSceNetCtl): keep the callback argument and deliver the state from sceNetCtlCheckCallback#6138fdfawef324 wants to merge 1 commit into
fdfawef324 wants to merge 1 commit into
Conversation
…rom sceNetCtlCheckCallback sceNetCtlRegisterCallback and sceNetCtlRegisterCallbackV6 stored only the function and dropped its argument, and sceNetCtlCheckCallback returned 0 without calling anything, so a title that polls sceNetCtlCheckCallback until its callback reports IPOBTAINED never got the event. Each callback slot now keeps the function, its argument and the last event it received; unregistration clears the slot. With no IPv4 callback registered, sceNetCtlCheckCallback returns 0 without querying the host. Otherwise it takes the state from the same host-interface predicate as sceNetCtlGetState, IPOBTAINED (3) or DISCONNECTED (1) (shadPS4 src/core/libraries/network/net_ctl_codes.h L27-29 @15abf68c9b52), marks the IPv4 slots whose last event differs and calls them on the calling thread with their argument after the lock is released, so a callback can unregister itself. Delivery once per state change and slot follows KytyPS5 src/libs/network.cpp @9e41d8320a27 (NetCtlCallbackSlot L3447-3451, NetCtlCheckCallback L3648-3661, NetCtlRegisterCallback L3687-3707); shadPS4 net_ctl_obj.cpp L47-57 delivers on every check instead, and the debt entry records the difference and that KytyPS5 calls the callbacks under its lock. sceNetCtlTerm clears both tables, as KytyPS5 NetCtlTerm (L3625-3633) does. V6 slots keep their argument but get no event, since no source says which call delivers them. NetCtlCallback is now an APS5_VABI pointer, so the Windows build calls the guest function with the System V ABI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
11 tasks done
|
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.
|
Merged
11 tasks done
This was referenced Oct 15, 2026
Contributor
|
Checked on Linux: Ubuntu 26.04 (WSL2), GCC 15.2.0, Release, this head (
Not checked: macOS, the title. AI-assisted: yes (Claude Code). |
11 tasks done
This was referenced Oct 16, 2026
Collaborator
|
Checked the diff against KytyPS5 |
This branch has not been deployed
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
Stop 2 of the Minecraft Preview bring-up (#1277), NetCtl half: "NetCtl must store the callback argument and deliver the state from
sceNetCtlCheckCallback". Onmain,sceNetCtlRegisterCallbackandsceNetCtlRegisterCallbackV6store only the function and droparg, andsceNetCtlCheckCallbackreturns 0 without calling anything, so a title that pollssceNetCtlCheckCallbackuntil its callback reports the connection state never gets it.NetCtlCallbackinSceTypes.hppis nowvoid (APS5_VABI *)(int, void*). WithoutAPS5_VABI, the Windows build would call the guest function with the Microsoft ABI. The captureless lambda inGuestSceNet.cppno longer converts to it, so it becomes anAPS5_VABIfunction.{func, arg, lastEvent}. Registration storesfuncandargin an empty slot and writes*cid; unregistration clears the slot. Error codes, and the result for an empty slot, are unchanged.sceNetCtlRegisterCallbackcallback registered,sceNetCtlCheckCallbackreturns 0 without querying the host.sceNetCtlGetStateuses:IPOBTAINED(3) while the host has a non-loopback address,DISCONNECTED(1) otherwise. The values come from shadPS4net_ctl_codes.hL27-29. Under the lock it marks the IPv4 slots whoselastEventdiffers. After the lock is released, it calls each of them on the calling thread asfunc(event, arg), so a callback can unregister itself without deadlocking (tested).network.cpp@9e41d832 (NetCtlCallbackSlotL3447-3451,NetCtlCheckCallbackL3648-3661,NetCtlRegisterCallbackL3687-3707). shadPS4net_ctl_obj.cppL47-57 delivers the state on every check instead. Neither model is measured on hardware, and the debt entry records the difference.NetCtlUnregisterCallbackwaits for a running check. Here they are called from a copy of their slots, so an unregister orsceNetCtlTermon another thread that returns while a check is in flight does not stop that check from calling the callback once more with its old argument. The debt entry records this.sceNetCtlTermclears both tables, as KytyPS5NetCtlTerm(L3625-3633) does.A Functional entry in
docs/dev/debt/libSceNetCtl.mdrecords that the delivery model comes from KytyPS5 and is not measured on hardware, that the state comes from the host interfaces, the in-flight call after a concurrent unregister, and that V6 callbacks get no event.Cost: on Windows the host query is two
GetAdaptersAddressescalls, the same as onesceNetCtlGetStateonmain. On this host a check with a callback registered costs about 8.6 ms when the host is idle and 10-23 ms while parallel builds run;sceNetCtlGetStatecosts the same. With no callback registered, a check returns before the query (under 1 us). A follow-up PR will cache the predicate on Windows (invalidated byNotifyUnicastIpAddressChange/NotifyIpInterfaceChange, or built onGetUnicastIpAddressTable) and retryGetAdaptersAddressesonERROR_BUFFER_OVERFLOW. Until then, an address added between the size query and the fetch reads as no address, as it already does forsceNetCtlGetState, and here it deliversDISCONNECTEDand thenIPOBTAINEDon the next check.This covers only the NetCtl half of stop 2. The NpManager half (state callbacks and SIGNED_OUT from
sceNpCheckCallback) is a separate change. Minecraft Bedrock (PPSA17221) is playable onmainwithout this change (#5744), so the change was not needed there. The Preview needs it for stop 2 of #1277. No open PR covers these functions; the last change to them was #5427 (RegisterCallbackV6/UnregisterCallbackV6). #6039 also appends todocs/dev/debt/libSceNetCtl.md; whichever merges second resolves a two-line append.Test:
guest_net_ctl(core/libs/tests/GuestNetCtl.cpp) now runs callback cases before its existing exit 77 for a host without an IPv4 address. The expected event comes fromsceNetCtlGetState, so the result does not depend on the host's connectivity.sceNetCtlTerm(cid 0 both times); it is never called.&probeand a check, the callback has been called exactly once, witharg == &probeand the expected event. A second check calls nothing.sceNetCtlTermis not called by a check after it. Registering again afterTermgets cid 0, and the next check delivers the current state again.Tested
Windows Server 2025 (10.0.26100), WinLibs MinGW-w64 GCC 15.2.0, Ninja, Release,
BUILD_TESTING=ON, onmaineea428c.mainwith only the new test:GuestNetCtl.cppdoes not compile on Windows, because anAPS5_VABIfunction does not convert tomain'sNetCtlCallback. Red, with theNetCtlCallbacktype change andmain'sExport.cpp:guest_net_ctlaborts (0xc0000409) in 2 of 2 runs on eea428c, 2 of 2 on 922abe6 and 3 of 3 on 153d5d4, because the callback is never called.sceNetCtlCheckCallbackalso walking the V6 table aborts (0xc0000409) in 3 of 3 runs, and this change with the callbacks called under the lock times out at 20 s (deadlock in the self-unregister case).guest_net_ctlpasses in 5 of 5 runs on eea428c and 6 of 6 on 922abe6 (0.4-1.3 s on a host running parallel builds), and 8 of 8 on 153d5d4. The host has an address, so the cases ran with event 3 and the test did not skip.ctest -R 'Net|net'on eea428c and on 922abe6: 9 of 9 passed (guest_net_ctl,guest_sce_net,guest_netctl_ap_dialog,guest_datagram_*,guest_socket_host_write_*).python tools/check_conventions.py --base upstream/main(the tools frommain): passed.git merge-treeagainst the open PRs that touch the same files (test: organize library tests and label CTest suites #6044, docs: fix Pages workflow link and separate library technical debt #6039, feat(libSceNpManager): retain the game presence callback and validate content restrictions offline #6023, fix(avplayer): correct audio-video playback timing and sync #5995, feat(libSceVideoOut): register PS4 display buffers #5991, fix(libSceNet): read SO_RCVTIMEO and SO_SNDTIMEO as a timeval in sceNetSetsockopt #5967, fix(libSceNet): let a datagram receive on an unbound socket wait on Windows #5966, feat(libSceAudioOut): implement sceAudioOutGetSystemState #5965, feat(libSceNet): return success from ShowIfconfig and ShowNetstat #5928, fix(libSceNet): stop Sackboy loading retries on peer sockets #5836, fix(savedata): read every sceSaveDataSetSaveDataMemory2 data entry at its 64-byte stride #5659, fix(libkernel): stabilize virtual-query layout across hosts #5611, fix(shader): accept TYPE=0 images during materialization #5473; fix(libSceNet): report SO_SNDBUF and SO_RCVBUF from sceNetGetsockopt #5536 has since merged and is in the base): the only conflict this change adds is the docs: fix Pages workflow link and separate library technical debt #6039 append to the debt file, described above.Not tested: Linux and macOS (there
APS5_VABIis empty and the test fails at runtime instead of at compile time), and any title. I did not run Minecraft Preview.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)🤖 Generated with Claude Code