Lifetime problem when spawning a thread with arc mutex

I don't understand why the code below fails

use std::sync::{Arc};
use futures::lock::Mutex;

struct A<'a>{
    a: &'a u8
}

impl<'a> A<'a>{
    pub fn run(a: Arc<Mutex<Self>>) {
        let stack_thread = std::thread::Builder::new()
            .spawn(move || {
                let a = a.clone();
            }).unwrap();
    }
}

Error:

error[E0477]: the type `[closure@src/lib.rs:11:20: 13:14]` does not fulfill the required lifetime
  --> src/lib.rs:11:14
   |
11 |             .spawn(move || {
   |              ^^^^^
   |
   = note: type must satisfy the static lifetime

Playground

Actually I have an idea. If I take the lifetimes of A and remove the a member, it works. So it is possibly rejecting a: Arc<Mutex<Self>> inside of the spawned thread. When you spawn a thread, the closure must have a static lifetime:

pub fn spawn<F, T>(f: F) -> JoinHandle<T> 
    where F: FnOnce() -> T, 
          F: Send + 'static, 
          T: Send + 'static

so it looks like the fact that a is passed inside of the closure, makes the closure be not 'static. But I don't see why, as a: Arc<Mutex<Self>> inside the thread lives as long as the closure. Could somebody explain in details what is happening? I'm confusing lifetime of things with lifetime of references, etc.

A reference is only valid for as long as the thing it points at. Putting the reference inside an Arc/Mutex does not change that — the thing that the reference points at is still only valid for however long it is valid for.

1 Like

The problem is less obvious because of Self in the type. The type is:

Arc<Mutex<A<'a>>>

which means it is borrowing from something external marked by 'a. That borrowed data lives somewhere else, outside of the Arc (if it was inside of the Arc, there would be no lifetime annotation).

Arc only stores the data that is inside of it, but references are specifically for not storing any data. So the data referenced by 'a is not protected by the Arc<Mutex<…>>, so overall the type is not fully thread-safe.

4 Likes