A lifetime of a variable reference inside Mutex

I'm doing some async programming. I have a store which represents the central location where everything is stored. I'll simplify the whole example to get to the point. In the store I save a message and an event for each such message that has a reference to the message.

Here's an example:

#[derive(Debug)]
struct Store<'a> {
    pub messages: Vec<String>,
    pub events: Vec<Event<'a>>
}
impl<'a> Default for Store<'a> {
    fn default() -> Self {
        Self {
            messages: vec![],
            events: vec![],
        }
    }
}

#[derive(Debug)]
enum Event<'a> {
    Send(&'a String),
}

I wrap the store into an Arc<Mutex> so it can be locked and cloned across the threads. Now the challenge here represents the lifetime of the reference of the Event.

    let storex = Store::default();
    let store = Arc::new(Mutex::new(storex));

    let mut lock = store.lock().unwrap();
    let txt = String::from("hello");
    let event = Event::Send(&txt); // `txt` does not live long enough
    lock.messages.push(txt); // cannot move out of `txt` because it is borrowed
    lock.events.push(event);
    drop(lock);

    let mut lock = store.lock().unwrap();
    let event = lock.events.pop();
    let message = lock.messages.pop();
    drop(lock);

    println!("{:?}", event);
    println!("{:?}", message);

The code above obviously doesn't work. How can I solve this?

Don't put lifetimes on your event or store structs. Use owned types such as String instead.

There's really a case where I need this :).

Ah, I didn't read closely enough. Your struct is self-referential because the events field has references into messages. Self-referential structs are not possible in safe Rust. Do something else, e.g. use reference counting or indexes.

2 Likes

Got it. Thanks.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.