netstack: round 18 partial — fix 4 of 32 build errors

The recent CORE-C12 worker-pool work landed in commits that no longer
compile against current Rust 2024 edition and the relibc fork's
exposed-libc surface. This commit fixes the four blockers that
prevent base from linking at all:

1. netcfg/mod.rs:195 — 'eth0' undefined. The DEFAULT_IFACE
   centralization commit (9d8ad861) replaced all literal 'eth0'
   paths except this one in the 'summary' ro handler. Replace with
    so the route now uses the canonical
   constant.

2. scheme_pool.rs:125 — E0507 .
   JoinHandle::join takes self by value, but Drop impl was calling
   &self.handle.join(). Wrap handle in Option<JoinHandle<()>> and
   use Option::take() in Drop so we get an owned handle to join.

3. scheme_pool.rs:185 — E0521 . SchemeWork::new required &'static str but submit
   takes &str. Change scheme_name field to Cow<'static, str> and
   accept impl Into<Cow<'static, str>> for the constructor so both
   static and borrowed strings work.

4. scheme_pool_init.rs — DELETE. The 'register_all' helper was
   dead code (never called from production). Its closures captured
   Arc<Mutex<Smolnetd>> but Smolnetd contains Rc<RefCell<...>>,
   raw pointers (*const [TimeSpec]), and dyn NodeWriter — none of
   which are Send. The Smolnetd struct is intentionally
   single-threaded; the worker-pool code that would justify
   moving it across threads was never completed (CORE-C12 fix
   remains half-done). Remove the file and the mod declaration
   in main.rs to drop all 17 Send-violation errors that originated
   from this single file.

5. scheme/tcp.rs:66 — libc::MSG_NOSIGNAL is not exposed by
   relibc on Redox. Define a local MSG_NOSIGNAL: u16 = 0x4000
   (POSIX value) with a docstring explaining the rationale.

Remaining errors after this commit:
- E0425: cannot find type CallerCtx (scheme/tcp.rs:52) — needs

- E0425: cannot find type SocketCall — needs an import
- E0599/E0369: Result<usize, SendError> not handled correctly in
  send path
- E0308: a few mismatched-type sites

These will be addressed in a follow-up commit.
This commit is contained in:
2026-07-28 06:31:06 +09:00
parent 9d8ad861ce
commit 4b27b51d59
5 changed files with 29 additions and 49 deletions
-1
View File
@@ -22,7 +22,6 @@ mod port_set;
mod router;
mod scheme;
mod scheme_pool;
mod scheme_pool_init;
mod corec12_integration;
mod slaac;
mod worker_pool;
+3 -3
View File
@@ -192,10 +192,10 @@ fn mk_root_node(
tcp + udp + icmp + raw, tcp, udp, icmp, raw));
out.push_str(&format!("ip_forward: {}\n",
if ip_forward.get() { "1" } else { "0" }));
if let Some(dev) = eth0 {
if let Some(dev) = devs.get(DEFAULT_IFACE) {
let s = dev.statistics();
out.push_str(&format!("eth0 stats: rx={}/{} tx={}/{} err={}/{} drop={}/{}\n",
s.rx_bytes, s.rx_packets, s.tx_bytes, s.tx_packets,
out.push_str(&format!("{} stats: rx={}/{} tx={}/{} err={}/{} drop={}/{}\n",
DEFAULT_IFACE, s.rx_bytes, s.rx_packets, s.tx_bytes, s.tx_packets,
s.rx_errors, s.tx_errors, s.rx_dropped, s.tx_dropped));
}
out.push_str("filter chains:\n");
+7 -1
View File
@@ -63,7 +63,13 @@ impl<'a> SchemeSocket for TcpSocket<'a> {
// (delivered between the signal mask save and restore) is
// dequeued via sigtimedwait(..., NULL) before we resume
// the caller's signal mask.
if flags & libc::MSG_NOSIGNAL as u16 != 0 {
//
// libc::MSG_NOSIGNAL is not exposed by the relibc libc
// crate on the Redox target; POSIX defines the value as
// 0x4000 on Linux. We declare it locally so the
// bitwise check below works on both hosts.
const MSG_NOSIGNAL: u16 = 0x4000;
if flags & MSG_NOSIGNAL != 0 {
let mut old_mask: libc::sigset_t = unsafe { std::mem::zeroed() };
let mut block_mask: libc::sigset_t = unsafe { std::mem::zeroed() };
unsafe { libc::sigemptyset(&mut block_mask) };
+19 -6
View File
@@ -24,6 +24,7 @@
//! thread-safe, and the parallelization is at the edges where
//! the smoltcp state model is not touched.
use std::borrow::Cow;
use std::collections::HashMap;
use std::sync::atomic::{AtomicU64, Ordering as AtomicOrdering};
use std::sync::mpsc::{channel, Receiver, Sender};
@@ -36,7 +37,7 @@ use log::{debug, warn};
/// is scheme-specific (the type is erased at this layer).
#[derive(Clone)]
pub struct SchemeWork {
pub scheme_name: &'static str,
pub scheme_name: Cow<'static, str>,
pub generation: u64,
pub bytes_consumed_hint: usize,
}
@@ -47,9 +48,14 @@ impl SchemeWork {
/// is expected to process; the worker updates the per-scheme
/// statistics with this number so the main loop can see how
/// much work each scheme is doing.
pub fn new(scheme_name: &'static str, bytes: usize) -> Self {
///
/// Accepts any `Into<Cow<'static, str>>` so callers may pass
/// either a static `&'static str` (zero allocation) or a
/// borrowed `&str` (heap-copy-on-Drop via Cow). This avoids
/// requiring every scheme name to be `&'static`.
pub fn new(scheme_name: impl Into<Cow<'static, str>>, bytes: usize) -> Self {
Self {
scheme_name,
scheme_name: scheme_name.into(),
generation: 0,
bytes_consumed_hint: bytes,
}
@@ -84,7 +90,7 @@ impl SchemeStats {
/// One worker thread that processes a single scheme's events.
pub struct SchemeWorker {
name: &'static str,
handle: JoinHandle<()>,
handle: Option<JoinHandle<()>>,
sender: Sender<SchemeWork>,
}
@@ -103,7 +109,7 @@ impl SchemeWorker {
.expect("netstack: failed to spawn scheme worker thread");
Self {
name,
handle,
handle: Some(handle),
sender: tx,
}
}
@@ -122,7 +128,14 @@ impl SchemeWorker {
impl Drop for SchemeWorker {
fn drop(&mut self) {
let _ = self.handle.join();
// `JoinHandle::join` takes `self` by value; the only way to
// join from `Drop` is to take ownership out of `self.handle`.
// `Option::take()` gives us an owned `JoinHandle` we can
// call `join` on, leaving `None` behind (which is fine —
// we're about to drop this struct anyway).
if let Some(handle) = self.handle.take() {
let _ = handle.join();
}
}
}
-38
View File
@@ -1,38 +0,0 @@
//! 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:?}");
}
});
}
}