Repository navigation
fix(libkernel): poll pipe descriptors - #3644
Conversation
|
Independent pre-review on Linux (full CI runs only happen on manual trigger, so recording one): CachyOS, kernel 7.2.9, GCC 16.2.1, Ninja, Release,
|
ProsperoTV (PPSA99003) stops after its menu opens because poll threw for the read end of a pipe it polls next to its sockets. poll now reports pipe readiness as FreeBSD's pipe_poll does: readable when data is buffered, POLLHUP once the other end is closed, writable when PIPE_BUF bytes are free. On Windows the pipe is checked with NtQueryInformationFile while the sockets are waited on in 1 ms slices; on Linux the host poll waits on both. A closed descriptor below the socket range reports POLLNVAL.
8cc3402 to
7250306
Compare
|
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.
|
|
Tested on Linux (CachyOS, RTX 2070, NVIDIA 615.71.09) with Nuvio Max'd (PPSA99288), built from Without this PR the title aborts about 14 s after start with AI-assisted: yes |
|
Independent Windows validation of this implementation, cleanly carried onto pinned main
Windows11 Enterprise26200, WinLibs GCC15.2.0r7 /Ninja Release/testing ON, bundled dependencies; RTX5080 driver610.62, AnyPS5 shader cache disabled. Driver-cache coldness and Linux execution are unverified in this campaign. Additional title needing the pipe path: Sonic Unleashed Recompiled, PPSA99902 /01.003.000. Our conditional #4822 libc-only replay stops on the original non-socket guard. A scalar observer confirms pipe read ends requesting POLLIN with timeout=-1 and count1; #3521's existing comment has the exact pair/event records. Kernel-only conditional title comparison completed: on the fixed-libc #4822 profile, the original libkernel aborts on non-socket poll after9.981s. Replacing only libkernel.prx with this implementation removes that observed abort. A captured frame was inspected and shows the SEGA startup logo; the process continues until 789.240s, then exits0xC0000409 without timeout at the existing private integration guard: The other123 library hashes, including the fixed libc, and executable hash are unchanged. Native selected groups ×5 and conventions/registration also pass on the experimental adaptation. Original executable/bundled libc, baseline runtime, converted guest and user data are restored/hash-verified; tracked source is clean. The four scheduled input pulses and two additional3000ms pulses are recorded separately; consumption and reliable menu navigation remain unverified. Early frame captures establish startup rendering, not gameplay or unique-frame FPS. The MSAA guard is local to the preserved experimental stack, already investigated in #2132/#419; this replay supplies no new actual guest-write/coherence verdict and does not justify a new main-defect issue or relaxing the guard. Validated experimental fork headfac106b2b. Bring-up: #4443. This validation does not select between the overlapping #3644/#3649 submissions or validate their combination with the low-socket-descriptor change #4391. AI-assisted: Codex; author responsible. |
|
Linux merges the 256-byte writes into 4 KiB pipe pages and reports AI-assisted: yes |
FreeBSD's pollscan clears POLLOUT whenever POLLHUP is set, so a write end whose read end is closed reports POLLHUP alone, with POLLIN and POLLRDNORM when they were asked for; both host paths reported POLLOUT | POLLHUP. POLLOUT on a read end now throws. FreeBSD opens both ends FREAD | FWRITE and pipe_poll reports the read end writable, which a one-way host pipe cannot back. guest_poll drained 1 KiB from the full pipe before expecting POLLOUT, but Linux reports it only once a whole 4 KiB page is free, so the test aborted there. It now drains the pipe, which is writable on every host.
|
Pushed 64ca6e3 on top of your commit, so this can be built:
The debt entry is updated to match. On Linux, merged with main: full build, ctest 995/995 (7 skipped), |
What
Fixes #3584.
pollthrewdescriptor N is not a socketfor any descriptor below the guest socket range. ProsperoTV (PPSA99003) polls the read end of apipenext to its sockets and stopped right after its menu opened, onmaina11c8f7f7, Windows, catalog build (eboot.binandsce_module/libc.prxunwrapped as #2605 requires):With this branch, run the same way, the menu finishes (
[TV] menu ready display=3840x2160 ... in 1259 ms), its catalog request goes out, and it stops later at the AGC stop that #3581 tracks for five other titles:Pipe readiness follows FreeBSD 11's
pipe_poll:POLLIN/POLLRDNORMwhen data is buffered;POLLIN/POLLRDNORMandPOLLHUP, and the write end reportsPOLLOUTandPOLLHUP;POLLOUTwhen at leastPIPE_BUF(512) bytes are free;On Linux the pipe goes to the host
pollwith the sockets. Linux reportsPOLLERRfor a write end whose reader is gone; that becomesPOLLOUT | POLLHUP, as on FreeBSD. On Windows a CRT pipe can't be waited on withWSAPoll, so while a pipe is in the set,pollreads its buffered and free bytes and the pipe state withNtQueryInformationFile(FilePipeLocalInformation, andFileAccessInformationfor the end's access) and waits on the sockets in 1 ms slices until something is ready or the timeout passes. Sets without a pipe wait exactly as before.A closed descriptor below the socket range now reports
POLLNVAL, as FreeBSD does and as closed sockets already did. Other descriptors there (regular files, terminals) still throw. TechnicalDebt'spollentry is updated.selecton non-socket descriptors is a separate path (Socket.cpp, #3462) and is unchanged.Tested
Windows 11 (26200), MinGW-w64 GCC 15.2.0 (WinLibs r7), Release, full build with
BUILD_TESTING=ONona11c8f7f7:ctest832/836 passed. The four failures fail the same way onmainhere:windows_exceptions(Windows: windows_exceptions fails since #1423, unwinding through runtime DLL frames (std::call_once) no longer reaches the catch #3411);guest_kernel_sys:symlinkthrowsFunction not implementedon Windows, which fix(libkernel_sys): create symlinks with CreateSymbolicLinkW on Windows #3510 addresses;guest_filesystem: restoring the directory time fails on Windows, which test(libkernel): don't require restoring the directory time on Windows #3518 addresses;agc_driver_emulated_color_compare: the GPU here cannot sample the sRGB image it uses.guest_pollnow also checks, on apipe:POLLIN | POLLRDNORMasked;POLLIN | POLLRDNORM | POLLHUPwith data left and once drained;POLLOUT | POLLHUPon the write end;POLLNVAL.It passed 20/20 runs. Mutation check, caught:
POLLHUP;POLLNVAL;One survived: writable at any free byte instead of 512. The test fills the pipe 256 bytes at a time, so it can't tell the two apart.
Not run on Linux (no Linux host here). The Linux path is the existing host
pollwith pipes added to the set, plus thePOLLERRmapping.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)