Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to get Mutex inner variable in CONFIG in once_cell #117

Closed
baoyachi opened this issue Oct 19, 2020 · 1 comment
Closed

how to get Mutex inner variable in CONFIG in once_cell #117

baoyachi opened this issue Oct 19, 2020 · 1 comment

Comments

@baoyachi
Copy link

baoyachi commented Oct 19, 2020

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
@baoyachi baoyachi changed the title how to get Mutex inner variable in once_cell how to get Mutex inner variable in CONFIG in once_cell Oct 19, 2020
@matklad
Copy link
Owner

matklad commented Oct 19, 2020

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

@matklad matklad closed this as completed Oct 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants