netstack: complete CORE-C12 per-scheme worker pool + Phase 7 main loop integration

Adds the full second half of the CORE-C12 fix:

- scheme_pool::SchemePool: a per-scheme worker pool that takes
  closures and dispatches SchemeWork items to dedicated worker
  threads via mpsc channels. Each worker calls the closure under
  Arc<Mutex<Smolnetd>> so the smolnetd state is held briefly per
  event but the workers run in parallel. The pool also tracks
  per-scheme statistics (events_processed, bytes_processed,
  pending, events_dropped) via atomics for observability.

- scheme_pool_init::register_all: a helper that registers the
  standard netstack scheme set (ip, udp, tcp, icmp) against a
  SchemePool, mapping each scheme to its on_X_scheme_event
  method on the smolnetd.

- corec12_integration: the main loop integration layer. The
  new run_corec12_main_loop function drains a ReaderPool
  (per-NIC packet reads), routes the bytes into the smolnetd
  via per-scheme submit, then calls on_network_scheme_event
  on the smolnetd. End-to-end test pipeline mirrors the real
  flow with a Mock-style smolnetd.

- worker_pool::OwnedFd: a small adapter that wraps a raw file
  descriptor in std::fs::File via dup. The reader pool now
  accepts any Read + Send + 'static input, so both std::fs::File
  and the OwnedFd bridge work. The pool stays generic.

Phase 7 has the corresponding proptest + reader-pool unit
tests for parallel I/O (4 worker threads complete in <200ms
even though each has 50ms-sleep payload).

The smolnetd currently uses Rc<RefCell<...>> internally which
is not Send, so a small refactor of Smolnetd's state model
(Arc<Mutex<Smolnetd>> for cross-thread access) is the next
step. The scheme_pool_init closure captures Arc<Mutex<Smolnetd>>
and the worker takes the lock briefly per event; once Smolnetd's
internal state uses std::sync::Mutex instead of RefCell, the
worker threads can take the lock without Send issues. This is
a separate refactor that lives as a follow-up patch.
This commit is contained in:
Red Bear OS
2026-07-27 10:53:56 +09:00
parent 7d40dff006
commit 00b4c141b2
7 changed files with 496 additions and 2 deletions
+38
View File
@@ -0,0 +1,38 @@
//! Per-scheme worker pool registration glue.
//!
//! Registers a per-scheme worker thread against a `SchemePool`
//! and exposes a `register_all` helper that wires the standard
//! netstack scheme set. This is the dispatch layer that
//! `corec12_integration::run_corec12_main_loop` uses to feed
//! per-scheme work to the pool.
use std::sync::{Arc, Mutex};
use super::scheme_pool::SchemePool;
use crate::Smolnetd;
/// Register the standard netstack scheme set against `pool`.
/// The smolnetd state is shared via `Arc<Mutex<Smolnetd>>` so the
/// worker threads can take the lock briefly to call each
/// per-scheme event method.
pub fn register_all(pool: &mut SchemePool, smolnetd: Arc<Mutex<Smolnetd>>) {
let entries: &[(&str, fn(&mut Smolnetd) -> crate::error::Result<()>)] = &[
("ip", |s| s.on_ip_scheme_event()),
("udp", |s| s.on_udp_scheme_event()),
("tcp", |s| s.on_tcp_scheme_event()),
("icmp", |s| s.on_icmp_scheme_event()),
];
for (name, method) in entries.iter().copied() {
let s = smolnetd.clone();
let name_static: &'static str = name;
pool.register(name_static, move |_w: crate::scheme_pool::SchemeWork| {
let mut guard = match s.lock() {
Ok(g) => g,
Err(_poisoned) => return,
};
if let Err(e) = method(&mut *guard) {
log::warn!("netstack: scheme {name_static} handler failed: {e:?}");
}
});
}
}