v4.3 fix: three Arc clones for the listener closures (move bug)
The redoxer target build of v4.3 failed with:
error[E0382]: the type `Arc` does not implement `Copy`
...
let scheme_for_events = Arc::clone(&scheme);
...
move || scheme_for_events_aer.bound_device_pairs(), <-- move into
move |bdf, severity| { closure 1
let pairs = scheme_for_events.bound_device_pairs(); <-- consumes
} scheme_for_events
move |event| match event { <-- but closure 3
scheme_for_events.dispatch_recovery(...); wants it too
}
Root cause: three closures (, ,
) all need access to the scheme. Each is `move` so
each must own its own Arc. Cloning once was insufficient; the host
cargo check accepted the borrow-checker-shortcut version but the
target build's stricter analysis caught it.
Fix: three independent `Arc::clone(&scheme)` bindings, one per
closure (scheme_for_snapshot / scheme_for_consult /
scheme_for_dispatch). Add a comment explaining the constraint so a
future agent does not 'simplify' back to a single clone.
Also remove the now-unused `scheme_for_events` binding.
Verified:
cargo check --target x86_64-unknown-redox clean (only pre-existing
parse_linux_id_table warning)
cargo check (host target) clean (same pre-existing)
cargo test --bin driver-manager 70 passed
cargo test --lib redox-driver-core 32 passed
This commit is contained in:
@@ -384,8 +384,6 @@ fn main() {
|
||||
&shared_blacklist,
|
||||
));
|
||||
|
||||
let scheme_for_events = Arc::clone(&scheme);
|
||||
|
||||
match manager.lock() {
|
||||
Ok(mut mgr) => {
|
||||
mgr.register_bus(Box::new(PciBus::new()));
|
||||
@@ -420,11 +418,18 @@ fn main() {
|
||||
// overrides), then to None (severity-only). The listener then
|
||||
// maps the action through `RecoveryAction::Fatal` -> escalation
|
||||
// log marker (in main callback) before calling dispatch_recovery.
|
||||
let scheme_for_events_aer = Arc::clone(&scheme);
|
||||
//
|
||||
// Each closure captures its own `Arc` clone of `scheme`. Cloning
|
||||
// once is not enough — the closures are mutually exclusive
|
||||
// (each runs on its own thread) and `move` semantics require
|
||||
// independent ownership for each.
|
||||
let scheme_for_snapshot = Arc::clone(&scheme);
|
||||
let scheme_for_consult = Arc::clone(&scheme);
|
||||
let scheme_for_dispatch = Arc::clone(&scheme);
|
||||
let _events_thread = unified_events::spawn_unified_listener(
|
||||
std::path::PathBuf::from("/scheme/pci/aer"),
|
||||
std::path::PathBuf::from("/scheme/pci/pciehp"),
|
||||
move || scheme_for_events_aer.bound_device_pairs(),
|
||||
move || scheme_for_snapshot.bound_device_pairs(),
|
||||
move |bdf, severity| {
|
||||
// 1) Sidecar IPC: ask the spawned driver daemon if it
|
||||
// opted in to error-reporting.
|
||||
@@ -440,7 +445,7 @@ fn main() {
|
||||
}
|
||||
// 2) In-process DriverConfig::on_error: drivers may
|
||||
// override the severity-default via the trait method.
|
||||
let pairs = scheme_for_events.bound_device_pairs();
|
||||
let pairs = scheme_for_consult.bound_device_pairs();
|
||||
let driver_name = match pairs.iter().find(|(addr, _)| addr == bdf) {
|
||||
Some((_, name)) => name.clone(),
|
||||
None => return None,
|
||||
@@ -498,7 +503,7 @@ fn main() {
|
||||
if let Some(action_str) =
|
||||
scheme::DriverManagerScheme::recovery_action_str(*action)
|
||||
{
|
||||
scheme_for_events.dispatch_recovery(&event.device, action_str);
|
||||
scheme_for_dispatch.dispatch_recovery(&event.device, action_str);
|
||||
}
|
||||
}
|
||||
unified_events::UnifiedEvent::Pciehp(e) => {
|
||||
|
||||
Reference in New Issue
Block a user