how to get Mutex inner variable in CONFIG in once_cell
baoyachi opened this issue · comments
baoyachi. Aka Rust Hairy crabs commented
how to get reference Ext
in CONFIG
use once_cell::sync::Lazy;
use std::sync::Mutex;
use std::collections::HashMap;
use std::fmt::Debug;
trait IExt: Debug + Send + Sync {
fn get_key(&self);
}
#[derive(Debug)]
struct Ext;
impl IExt for Ext {
fn get_key(&self) {}
}
static CONFIG: Lazy<Mutex<HashMap<String, Box<dyn IExt>>>> = Lazy::new(|| Mutex::new(Default::default()));
fn add() {
CONFIG.lock().unwrap().insert("1".to_string(), Box::new(Ext));
}
fn get_key<'a>() -> &'a Box<dyn IExt> {
CONFIG.lock().unwrap().get("1").unwrap()
}
fn main() {
add();
let key = get_key();
println!("{:?}", key);
}
compile error:
error[E0515]: cannot return value referencing temporary value
--> src/main.rs:27:5
|
27 | CONFIG.lock().unwrap().get("1").unwrap()
| ----------------------^^^^^^^^^^^^^^^^^^
| |
| returns a value referencing data owned by the current function
| temporary value created here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0515`.
error: could not compile `rustls-example`.
To learn more, run the command again with --verbose.
Process finished with exit code 101
Alex Kladov commented
That's not possible, because that would be unsfae.You are trying to return a pointer inside the value, protected by the mutex, but the pointer is not protected by a lock guard. That means that some other thread could sucesfully lock the mutext and mutate the protected data, invalidating the pointer. You need to either clone the data (using Arc<dyn IExt>
would help) or use something like map from parking lot: https://docs.rs/lock_api/0.4.0/lock_api/struct.MutexGuard.html#method.map