So far tried boxing, Arcs, Arc Mutex, and various other solutions I found online, but I cannot get them to work.
error[E0277]: `(dyn Fn() + 'static)` cannot be sent between threads safely
--> src\main.rs:192:19
|
192 | thread::spawn(move|| {
| _____-------------_^
| | |
| | required by a bound introduced by this call
193 | | threade_state.lock().unwrap()
194 | | .callback_store.callbacks.iter()
195 | | .for_each(|(id, callback_arc)| {
... |
199 | | });
200 | | }).join();
| |_____^ `(dyn Fn() + 'static)` cannot be sent between threads safely
|
= help: the trait `Send` is not implemented for `(dyn Fn() + 'static)`
= note: required for `Mutex<(dyn Fn() + 'static)>` to implement `Sync`
= note: required for `Arc<Mutex<(dyn Fn() + 'static)>>` to implement `Send`
= note: required because it appears within the type `(String, Arc<Mutex<(dyn Fn() + 'static)>>)`
= note: required for `hashbrown::raw::RawTable<(String, Arc<Mutex<(dyn Fn() + 'static)>>)>` to implement `Send`
= note: required because it appears within the type `hashbrown::map::HashMap<String, Arc<Mutex<(dyn Fn() + 'static)>>, RandomState>`
= note: required because it appears within the type `HashMap<String, Arc<Mutex<(dyn Fn() + 'static)>>>`
use std::collections::HashMap;
use std::sync::{Mutex, Arc};
use std::thread;
struct CallbackStore {
callbacks: HashMap<String, Arc<Mutex<dyn Fn() -> ()>>>
}
struct State {
pub numbers: Vec<u64>,
pub age_by_name: HashMap<String, u64>,
pub callback_store: CallbackStore,
}
async fn callback_horror() {
let mut state = Arc::new(Mutex::new(State {
numbers: vec![1, 2, 3, 4, 5],
age_by_name: HashMap::from([
("jeff".to_owned(), 42),
("joe".to_owned(), 43),
("doe".to_owned(), 29),
]),
callback_store: CallbackStore {
callbacks: HashMap::new(),
},
}));
let add_state: Arc<Mutex<State>> = Arc::clone(&state);
let mut add_callback = move || {
let mut asd = add_state.lock().unwrap();
asd.numbers.push(123);
};
state.lock().unwrap().callback_store.callbacks.insert(
"adddomg_123_callback".to_owned(),
Arc::new(Mutex::new(add_callback)));
let delete_state: Arc<Mutex<State>> = Arc::clone(&state);
let mut delete_callback = move || {
state.lock().unwrap().age_by_name.remove("jeff");
};
state.lock().unwrap().callback_store.callbacks.insert(
"delete_jeff_callback".to_owned(),
Arc::new(Mutex::new(delete_callback)));
let threade_state: Arc<Mutex<State>> = Arc::clone(&state);
thread::spawn(move|| {
threade_state.lock().unwrap()
.callback_store.callbacks.iter()
.for_each(|(id, callback_arc)| {
println!("calling callback id: {}", id);
let callback = callback_arc.lock().unwrap();
callback();
});
}).join();
}
fn main() {
callback_horror();
}