feat(serve): supervised listener pool (v0.2 chunk 1)

OneForOne supervisor on the root actor, Restart::Permanent per listener.
ChildSpec factory owns its fd via Arc<OwnedFd> (OwnedFd gains Sync);
restarts reuse the fd — no re-dup, no fd-less window. wait_readable
failure now exits-and-restarts instead of being fatal. Conn actors stay
unsupervised bare spawns. Test hook INJECT_LISTENER_PANICS panics before
accept so a pending connection must survive into the restarted listener.

Roadmap: chunk 1 marked done; chunk 3 fork resolved to smarm-native
timed waits (RFC 008 landed at 393cdd0, reaper option removed); chunk 2
drain-then-stop decided; v0.4-3(b) unblocked.
This commit is contained in:
Claude
2026-06-11 12:07:19 +00:00
parent 3da553b9b2
commit 5fe696992a
4 changed files with 181 additions and 67 deletions
+7
View File
@@ -52,6 +52,13 @@ impl Drop for OwnedFd {
// becomes the unique closer.
unsafe impl Send for OwnedFd {}
// SAFETY: shared references only expose `as_raw(&self)` — reading an
// integer. No interior mutability; `into_raw` takes `self` by value and is
// unreachable through a shared reference. Needed so a supervisor
// `ChildSpec` factory (an `Fn` closure, hence shared across restarts) can
// own its listener fd via `Arc<OwnedFd>`.
unsafe impl Sync for OwnedFd {}
// ---------------------------------------------------------------------------
// bind_and_listen
// ---------------------------------------------------------------------------