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:
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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) };
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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:?}");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user