I need to have a mutable collection of Mutex that needs to be shared between multiple threads. The purpose of this collection is to return for a given key a list of MutexGuard (to be able to synchronize the threads depending on the key). Please note that when initialized, the collection has no Mutex in it, these need to be created at runtime depending on the key.
My code is the following:
use std::collections::HashMap;
use std::sync::{Arc, Mutex, MutexGuard};
struct Bucket {
locks: HashMap<String, Mutex<()>>,
}
impl Bucket {
// This method will create and add one or multiple Mutex to the
// collection (therefore it needs to take self as mutable), according
// to the give key (if the Mutex already exist it will just return
// its MutexGuard).
fn get_guards(
&mut self,
key: impl Into<String>,
) -> Vec<MutexGuard<'_, ()>> {
let lock = self.locks.entry(key.into()).or_default();
vec![lock.lock().unwrap()]
}
}
impl Default for Bucket {
fn default() -> Self {
Self {
locks: HashMap::new(),
}
}
}
fn main() {
// I need to wrap the bucket in a Arc<Mutex> since it's going to be shared
// between multiple threads
let mut bucket = Arc::new(Mutex::new(Bucket::default()));
// Here I need to get a list of guards, so that until they are dropped
// I can synchronize multiple threads with the same key (or to be more
// precise with the same MutexGuards, as different keys may yields the
// same MutexGuards).
let guards = {
// IMPORTANT: I need to unlock the Mutex used for the `bucket` (with
// write access) asap, otherwise it will nullify the purpose of the
// bucket, since the write lock would be hold for the whole `guards`
// scope.
let mut b = bucket.lock().unwrap();
b.get_guards("key")
};
}
The error I am getting is the following:
error[E0597]: `b` does not live long enough
--> src/main.rs:29:9
|
27 | let _guards = {
| ------- borrow later stored here
28 | let mut b = bucket.lock().unwrap();
29 | b.get_guards("key")
| ^ borrowed value does not live long enough
30 | };
| - `b` dropped here while still borrowed
error: aborting due to previous error
Is there a way to design my Bucket collections of Mutex so that I can achieve my goal?