Follow-up to #66 and #461. Home currently delivers no MessagePort close events; Node emits one asynchronous close event for both endpoints. Reproduction: tests/runtime/worker-close-events.pending.mjs fails with MessagePort close events missing. MessagePort.cpp close() immediately removes listeners, detached dispatch is rejected, and MessagePortPipe.cpp neither notifies the peer nor registers unstarted peers for close notification. Implement the native lifecycle, preserving wrappers until dispatch and suppressing events safely during VM teardown. Do not use a JavaScript-only close shim: it misses remote closure and transfer/teardown behavior. Acceptance: both endpoints, once-only, asynchronous delivery, transfer and worker teardown coverage, without queue or reference leaks. Synchronous message-presence fixes in #461 do not resolve this separate gap.
Native worker parity: emit asynchronous MessagePort close events on both endpoints
#462Read-only implementation plan: additionally own unified webcore-4 (swap only MessagePortPipe.cpp; preserve31 companion includes) alongside current owned webcore-3. Selected MessagePort/MessagePortPipe headers currently byte-match Home; preserve ABI layouts and verify header compatibility. Register endpoint identity independently from message start/readiness; coalesce asynchronous both-end closure. Preserve peer messages already accepted before sender close, plus microtask ordering. Pending closure must survive transfer and recheck context/port identity, including same-context reattachment. Keep JS wrapper/listeners reachable until dispatch, suppress JS during context destruction, and release references exactly once. Do not broadly permit all detached-port events. Add FIFO-before-close, cross-worker, transfer-before-dispatch, repeated close and shutdown controls before promoting the pending regression. Full pipe fixture has actually passed10 tests with3 upstream skips and516 assertions; native name filtering remains unwired, so selecting a small test-name subset is not currently reliable.
Implementation now rebuilding in Home: own native MessagePortPipe.cpp in unified webcore-4 while preserving31 external companion sources; validate exact MessagePort/pipe class-header ABI before generation; private state bits add peer-close and delivered markers without changing class layout. Closure preserves peer FIFO/unread data, sends old-wrapper close on transfer, rechecks context and endpoint identity, and gates JS on Home VM Running status during shutdown. Optional Node close callbacks preserve EventTarget identity/receiver/Event arguments; on(close) uses zero arguments. Twelve bounded Node reference controls pass, including immediate versus delayed synchronous reads, same-context reattachment, cross-worker closure, termination and GC. Independent review caught/fixed strong-ref destruction under pipe locks and a concurrent-GC reachability gap. Generator/ABI8tests69asserts and Zig helper4tests pass. Native runtime verification is pending; this is not yet a passing/complete claim.
Verification update: 13 native close cases and 14 prior native regressions pass. The pipe suite is 10 pass / 3 upstream skips / 516 assertions after explicitly retaining its FinalizationRegistry until reporting (the registry, not its targets; all assertions preserved). Closed-port and nested-transfer leak tests pass 4/4. A deeper unchanged worker context-destruction test consistently fails at roughly +34 MB RSS against its 30 MB limit. Teardown GC was scheduling pipe-owning tasks onto an already-stopped loop while the context remained registered. A targeted owning-context scheduling gate is building now; live remote peers and asynchronous local delivery must remain correct. No threshold increase or hidden retry pass. Full port remains incomplete under #66 and #461.
Implemented and verified locally in commit 007858c (Chris Breuer sole author/committer, no coauthors).
Home now owns MessagePortPipe.cpp alongside MessagePort.cpp and the worker builtin. Native close delivery is asynchronous/exactly once on both endpoints; peer FIFO data, unstarted queues, transfers, same-context reattachment, callback identity/arguments, GC liveness and teardown suppression are covered. Build preflight rejects class-header ABI drift and preserves external companion implementations. Teardown-GC scheduling checks the VM on its owning context outside registry/pipe locks; the unchanged context RSS test now passes, with its 30 MB limit preserved.
Final verification: native build + cached rebuild 13/13; all 15 native regression files pass; 13 close cases pass in Home and Node 24.18.0 controls. Three corpus files: 15 pass, 3 upstream skips, 0 fail, 529 assertions (pipe 10/516; closed-port leak 4/10; context teardown 1/3). Context teardown also passed three isolated repetitions after three reproducible pre-fix +34 MB failures. FileHandle and transfer/terminate standalone fixtures pass with real exit cleanup. Generator/ABI 8 pass/69 assertions; Zig helper 4 pass.
The pipe fixture explicitly retains only its FinalizationRegistry until reporting, then releases it; unchanged assertions now observe all 200 finalizations. Original pending close regression passed and was replaced with the broader native suite. General queued-task cancellation remains #465; synchronous receive during pending local close remains #466. No 100% worker/full-port claim. About 1.4 GiB of superseded owned binary caches removed; latest verified binary retained.
Publication remains pending: normal git push to codex/runtime-port fails DNS resolution for github.com. This issue stays open until publication/review; do not infer remote availability from the local commit SHA. Parent #66; related #461.
Publication gate is now satisfied. 007858c52 is reachable on current main and contains the owned asynchronous MessagePort close lifecycle verified above: both endpoints, exactly-once asynchronous events, FIFO preservation, transfers/reattachment, GC reachability, and teardown suppression. Pending synchronous receive is separately published in #466 and generic task ownership remains #465. Closing this bounded close-event issue as completed.
Sign in to comment on this issue.