Skip to content

feat(libkernel): support deferred cancellation in POSIX accept - #12965

Open
Felipebmaitan wants to merge 116 commits into
boykopovar:mainfrom
Felipebmaitan:feat/posix-connection-cancellation
Open

Felipebmaitan wants to merge 116 commits into
boykopovar:mainfrom
Felipebmaitan:feat/posix-connection-cancellation

Conversation

@Felipebmaitan

@Felipebmaitan Felipebmaitan commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

What

Current integration head e654da0e29634148ad5aa93c82edeb79236c1222 preserves published accept e01288c9204944ae5befa08a514fb7d93443ac03 and composes writes 86dfdc9f090cc58983b78d0808a8fde1756415e4, including #12149 and the reads underscore-context repair. Current accept-only comparison. The Windows sigjump hang reported by @JJenkx is still unresolved. This update adds a bounded diagnostic guard, not a claimed lost-wake repair. Earlier maintenance descriptions below are historical.

POSIX accept and _accept now wake on enabled deferred cancellation. The listener remains admitted through the native operation. An accepted native socket stays privately owned through deferred signal delivery; cancellation, thread exit or longjmp at that boundary disposes it before guest cleanup/TSD. Completed acceptance wins a pending cancellation request. libSceNet gains no cancellation point.

This accept slice ships the ownership mechanism with its first consumer and tests. Connect is a separate follow-up. Incremental scope: 7 files, 249 insertions, 7 deletions.

Stack targeting main: #10817 / #10755, then #12682, then #12688, then #12700, then this PR. Exact prerequisite commits/authorship are preserved. The writes prerequisite resolves the shared socket/cancellation integration order agreed with its author; it does not expand the accept topic.

Overlap checks were run. The #12700 overlap is resolved by the declared writes -> accept order and exact prerequisite merge. Nearby #11896 (receive flags), #10645 (socket events) and #10552 (macOS) do not implement this slice. The final scan also reports #7485 (accept address/length error precedence) and #12467 (UDP disconnect naming): those remain separate behavior changes; this slice preserves existing argument errors and does not claim to resolve their merge ordering. The refresh scan covered 1,454 open PR heads. Other reported overlaps are inherited in the composed prerequisites (#7090, #8463, #9019, #9938, #11625, #11831, #12005, #12130, #12135, #12170 and #12642); some stale branches cannot be compared automatically. This does not claim the whole stack is conflict-free with every open PR. No additional author agreement is implied.

Tested

Fresh Linux-only validation: Ubuntu 24.04.5 x86-64 container through Apple Silicon translation, GCC 13.3, Release. Production runtime libraries and focused accept/context/jump/stream/socket executables build; 39/39 selected CTests pass, followed by 100/100 guest_io_context_sigjump repetitions (22.90 s total). Reads passed its 16-test selection plus the missing-restore negative control; transport passed 26/26 after an explicit stale-object rebuild; writes passed 364 selected cases. Conventions pass with the inherited SSL debt-length warning. No fresh Windows runtime, native macOS, title, console, GPU or performance run. A Linux repeat is not evidence that the reported Windows race is fixed. Upstream Windows workflow dispatch was denied HTTP 403 (admin rights required); no linked Windows environment API is callable in this session. Exact-head CI and maintainer bench remain outstanding. All evidence is pinned to upstream main de824c2919ca65086c6324a1e0388866a7327eea; upstream advanced to 18f594978831b1cac65bcc02cc0047781844c39d after the final push and that newer composition has not been validated. Earlier results below apply only to their stated historical heads.

Final composed head e01288c9204944ae5befa08a514fb7d93443ac03:

  • Preserves exact published reads feat(libkernel): cancel blocked POSIX reads with owned operations #12682 55161f97476a8bd413c279829cabb6390307e4d5, transport fix(libkernel): preserve blocking sockets over nonblocking native transport #12688 5dce7fea277f92c9e74db908ba1a0a5e0ebbe5c6, writes feat(libkernel): cancel blocked POSIX writes with partial progress #12700 daa3a810cbb43e399e3912df6bf3edb4221ef98c, their prerequisites and current main 08a10d225306ad102b57408e2ef7566bcfb829b2 via clean merges. The composed-base commit exists only to provide an exact incremental comparison.
  • Windows x86-64 build 26300, WinLibs GCC Release/Ninja and Linux x86-64 WSL2/GCC13 Release/Ninja: production libc/libkernel/libSceNet dependency graph and focused executables rebuilt. 618 distinct Windows / 699 distinct Linux runtime cases passed across the main selection and a separate three-case run. Initially the three net_dontwait_blocking_* cases were Not Run because their separate executable was omitted from the target list; after building net_blocking_send_tests, all three passed on both platforms. No executed case failed.
  • Selection: ^guest_accept_|^guest_io_(write|read|recv|signal|descriptor|close|context)|^guest_socket_(options|connect_listening|stream_options|event|dontwait)|^guest_stream_close|^net_dontwait. Includes all 13 accept cases, read/write/borrowed-descriptor/context/close regressions, socket events and nonblocking receive cases. The inherited PEEK-readiness fixture and default SendBytes initialization fix remain intact; no TCP atomicity, data-loss or performance claim is made.
  • Final Windows guest_io_context_sigjump: another 100 repetitions with --output-on-failure, unchanged 15-second timeout, all passed.
  • Public-header audit: 373 libraries / 14,243 exports. Conventions: 0 errors; inherited libSceSsl debt-length warning. git diff --check passes.
  • Prior independent micro/macro reviews of original accept and writes/accept integration found no confirmed defects. The latest clean composition preserves the identical accept production/test patch ID fd67319c67d4cc796660bad8823d49be873cc5b2 versus composed base 75b5ef3210dc6ad1e843b0419a4b02d30b92633e. Upstream reviewed the new writes default-buffer fix separately. No new accept implementation was introduced by this refresh.

Unresolved reviewer hang: Windows 22621 report remains unexplained, not dismissed as load or classified as a confirmed lost wakeup. On Windows 26300, exact old accept 23691a5aa0f29643b2649f840732e3fd91b4ba57 and composed writes baseline d828f6cca320e8c1b335a86d401be40a45a2c977 each passed 200 isolated CTest repetitions plus 1,000 process runs with a three-second stall detector and bounded GDB all-thread capture on stall. No stall occurred, so no failure stack was obtained. Another 1,000 temporary phase-instrumented accept runs passed. Instrumentation was removed; the restored exact accept head passed 23 context/accept cases ten times each. The cumulative harness and admission/exception code were compared against the prerequisite, not main, which lacks this harness. No problematic interleaving or general runtime fix was confirmed. The original reviewer's OS and preceding full-suite execution were not reproduced; logging changes scheduling. No diagnostic code remains.

Address-waking tests were outside this focused selection. The known inherited failures remain unresolved; an upstream green writes run does not establish a fix.

Limits: no PS5 measurement, macOS runtime run, TCP/cancellation title run or performance claim. Descriptor-installation failure and disposal ordering before cleanup/TSD are statically reviewed, not directly fault-injected/asserted. General asynchronous cancellation and fresh native signals/nonlocal exits outside the controlled I/O boundary remain out of scope. Known gaps remain in docs/dev/debt/libkernel.md.

Checklist

lgqdaxia and others added 30 commits October 25, 2026 22:47
Keep native signals arriving beyond the receive timeout and bound the retained-owner wait. The same fixture rejects a source variant that incorrectly restarts its deadline after EINTR.

AI-assisted: Codex
Read O_NONBLOCK from the native socket for every retained transfer so descriptor aliases and passed sockets do not turn nonblocking I/O into a blocking wait. Keep guest timeout accounting and native query errors intact.

AI-assisted: Codex
Exercise real native descriptor aliases switching both blocking directions and a saturated nonblocking send after the guest descriptor closes, independently of SCM_RIGHTS.

AI-assisted: Codex
@Felipebmaitan

Copy link
Copy Markdown
Contributor Author

@JJenkx Investigated your report at #12965 (comment); the Windows hang remains unaddressed as a runtime defect.

Current integration head e654da0e29634148ad5aa93c82edeb79236c1222 preserves published accept e01288c9204944ae5befa08a514fb7d93443ac03 and composes writes 86dfdc9f090cc58983b78d0808a8fde1756415e4, including #12149 and the reads underscore-context repair. Current accept-only comparison. The Windows sigjump hang reported by @JJenkx is still unresolved. This update adds a bounded diagnostic guard, not a claimed lost-wake repair. Earlier maintenance descriptions below are historical.

Fresh Linux-only validation: Ubuntu 24.04.5 x86-64 container through Apple Silicon translation, GCC 13.3, Release. Production runtime libraries and focused accept/context/jump/stream/socket executables build; 39/39 selected CTests pass, followed by 100/100 guest_io_context_sigjump repetitions (22.90 s total). Reads passed its 16-test selection plus the missing-restore negative control; transport passed 26/26 after an explicit stale-object rebuild; writes passed 364 selected cases. Conventions pass with the inherited SSL debt-length warning. No fresh Windows runtime, native macOS, title, console, GPU or performance run. A Linux repeat is not evidence that the reported Windows race is fixed. Upstream Windows workflow dispatch was denied HTTP 403 (admin rights required); no linked Windows environment API is callable in this session. Exact-head CI and maintainer bench remain outstanding. All evidence is pinned to upstream main de824c2919ca65086c6324a1e0388866a7327eea; upstream advanced to 18f594978831b1cac65bcc02cc0047781844c39d after the final push and that newer composition has not been validated. Earlier results below apply only to their stated historical heads.

The source audit followed TryDeliver → queued APC → WakeIoDelivery, SignalManager::Run, NativeIo admission/check/unregister, and delivery/context retirement. The manager already retries interruption while delivery is pending, and native calls already check interruption after registration; I did not establish a particular lost-wake interleaving from source. I have not changed that production protocol speculatively.

GuestIoContext.cpp now has an independent 10-second watchdog, below the existing 15-second CTest limit. If the controller blocks inside an admission observation or sceKernelRaiseException, it prints I/O context stalled: stage=<stage> phase=<phase> and aborts, instead of losing all progress information at the outer timeout. Normal admission/completion waits retain their two-second bounds. This provides a useful failing-run diagnostic; it does not reproduce or fix your observed Windows hang. A native Windows reproduction with this guard, ideally with thread stacks, is still needed before selecting a production repair. No claim is made about relative failure rates.

AI-assisted: yes. No PR merged/replaced and no history rewritten.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants