Repository navigation
libkernel: fcntl record locks throw on Windows (ProsperoRadio, ProsperoTV after #3649); fix branch ready #4479
Description
With #3649 applied, ProsperoRadio (PPSA99001) stops on #3840's recorded Windows limit: what(): fcntl: record locks are not implemented on Windows, command=12, fd=3 (F_SETLK, at 33.7 s in download0/prosperoradio.log); with the POLLPRI fix (#4478) applied as well, ProsperoTV (PPSA99003) reaches the same line.
Fix branch ready: screamm:feat/libkernel-record-locks-windows: b7cc2856 on top of #3649's two commits on main 33ae282e (depends on #3649 only for the title evidence; the commit itself touches DescriptorControl.cpp and the fcntl test). I cannot open it as a PR under the intake rule while #4081 is open; anyone eligible is welcome to carry it, keeping the commit as is.
F_GETLK,F_SETLK,F_SETLKWand the oldF_OGETLK/F_OSETLK/F_OSETLKWforms now work on Windows with FreeBSD 11.4's checks in FreeBSD's order (kern_fcntlkern_descrip.c:607-752,lf_advlockasynckern_lockf.c:433-487,vop_stdadvlock,8c639945):SEEK_CURresolved against the current offset (EOVERFLOWpast the maximum, a directory using its emulated cursor),EBADFfor a read lock on a descriptor without read access or a write lock without write access (F_GETLKchecks the type but not access),EINVALfor a bad type, negative start, unknown whence or a negative length reaching below 0,EOVERFLOWforSEEK_ENDpast the maximum;F_GETLKwrites backF_UNLCKwith the adjusted start (24 bytes for the old form). Two cases still throw: aSEEK_ENDlock on a directory (size unknown) and locks on character devices. Linux is unchanged.- No lock table and no
LockFileExbacking, deliberately: FreeBSD'slf_blockslets only locks of different owners conflict, and every lock belongs to the process, so inside the single guest processF_SETLKnever returnsEAGAIN,F_SETLKWnever waits andF_GETLKalways reportsF_UNLCK; merge/split and release on close are unobservable. Windows byte-range locks are mandatory and would block the guest's own other descriptors (a shared lock blocks writes even through the locking handle), which breaks the POSIX semantics, so other host processes neither see nor are seen by these locks; recorded in the fcntl TechnicalDebt bullet. A table is a contained addition if multi-process support ever arrives. guest_kernel_fcntl: the old Windows "throws" expectation becomes the Linux round trip, plus a newRecordLocksBelongToTheProcesssection (round trips, overlap merge and split sequences, two descriptors on one range, a second thread'sF_SETLK/F_SETLKW/F_GETLKwithout conflict,SEEK_CUR/SEEK_END, negative lengths, the 24-byte struct,EINVAL,EBADFon read-only and write-only descriptors, relock after close,EBADFafter close); theEOVERFLOW, error-ordering,F_GETLKwithF_UNLCKand directory cases are Windows-only, pending Linux CI for the shared part.
Tested on Windows 11 Pro 26220, WinLibs MinGW-w64 GCC 15.2.0 r7, Ninja, Release, BUILD_TESTING=ON, full build including libs: guest_kernel_fcntl, guest_poll, guest_dup, guest_file_vector 3/3; ctest -j8 -E "^agc_driver_|^video_out_flip" 620/620; conventions and git diff --check pass. ProsperoRadio relinked against this build (run 4 runtime, 60 s) opens /download0/radio-browser.sqlite3, starts its service and reaches its HTTP code, then stops at 16.5 s on what(): poll: POLLPRI is not supported by WSAPoll (#4478's fix). Not run on Linux.
Written with Claude Code assistance (implementation by a subagent, reviewed and validated in this session).
Activity
ag6393163475-lab commentedon Oct 12, 2026
Hi! I'd like to work on this issue. Is it still available?
If so, I'll start on a fix and open a PR once you confirm. Thanks!
milescoviello commentedon Oct 12, 2026
Carried in #4480, keeping your commit and authorship; it cherry-picks onto current
mainwithout #3649 and builds there. I added the Linux run the issue left to CI: Ubuntu 24.04, GCC 13.3,guest_kernel_fcntl,guest_poll,guest_dupandguest_file_vectorpass and all 306guest_*tests pass; the sharedRecordLocksBelongToTheProcesscases also pass withmain'sDescriptorControl.cpp, so Linux is unchanged. I can't run Windows here, so the Windows results in the PR are yours from this issue. Thanks for the branch.@ag6393163475-lab, since a finished fix branch was already here, I carried it as the issue asks rather than starting a new one.
AI-assisted: yes
screamm commentedon Oct 12, 2026
Combined run on Windows (
main33ae282e+ #3649's two commits + the POLLPRI fix from #4478 + the record-lock fix from #4479, all cherry-picking cleanly; run 4 runtime with that build's libs and relinker, 60 s each): ProsperoRadio (PPSA99001) and ProsperoTV (PPSA99003) get pastpolland the record locks and now stop on the graphics side,[videoout] presentation failed: AGC graphics: last provoking vertex with explicit per-vertex flat interpolation is unsupported(open #4030); PSXS5 (PPSA97510) runs the whole minute atPSXS5 | FPS: 59.93 (2867); SwanStation (PPSA98510) runs the whole minute (SwanStationPS5 ready, pad detected, its gamedb download fails with curl 7). No library stop is left in these four that lacks a PR. One observation for later: every HTTPS request from inside the guest fails immediately in these titles (Failed to connect to all.api.radio-browser.info port 443 after 75 ms,curl 7) while the same URLs answer from the host shell; it produces no stop line, and PSXS5 logged it before these fixes too. (#4480 carries this fix; thanks.)