why can't the following mutex be shared by multiple threads?

67 Views Asked by At

Considering the following code:

    pub fn with_lock<T>(f: &dyn Fn(&mut Connection) -> T) -> T {
        let mut guard = Connection::mutex().lock().unwrap();
        let re = f(&mut *guard);
        re
    }

    pub fn start() -> Result<()> {
        let fusion = Arc::new(any_fusion()?);
        let fusion_clone = Arc::clone(&fusion);
        let fusion_m = Mutex::new(fusion_clone);

        let handle = thread::spawn(|| {
            // Task to be executed in the new thread
            loop {
                fusion_m.lock().unwrap().update();
            }
        });

        Self::with_lock(&|c| {
            c.fusion = Some(*fusion);
            c.thread = Some(handle);
        });

        Ok(())
    }

When compiling, I have the following error:

error[E0277]: `dyn Fusion` cannot be shared between threads safely
   --> src/lib.rs:189:36
    |
189 |           let handle = thread::spawn(|| {
    |  ______________________-------------_^
    | |                      |
    | |                      required by a bound introduced by this call
190 | |             // Task to be executed in the new thread
191 | |             loop {
192 | |                 fusion_m.lock().unwrap().update();
193 | |             }
194 | |         });
    | |_________^ `dyn Fusion` cannot be shared between threads safely
    |
    = help: the trait `Sync` is not implemented for `dyn Fusion`
    = note: required for `Unique<dyn Fusion>` to implement `Sync`

this error is strange, as none of the variable used in the spawn closure has the type dyn Fusion, the only relevant variable fusion_m has the type Mutex<Arc<dyn Fusion> returned by any_fusion(), which should always be safe for synchronous access.

What's the cause of this error and how to make the compiler recognise the type of fusion_m properly?

0

There are 0 best solutions below