I have a vector of enum elements I'd like to access in a thread-safe manner.
I have interfaces that need to degrade the enum values to an option, as to not expose the inner structures to the public API.
For that I have enclosed each of the vector elements into an RwLock:
enum Container<T>{
Empty, Emptied, Full(T)
}
use std::sync::{RwLock, RwLockReadGuard};
struct Ship<T>{
content: Vec<RwLock<Container<T>>>
}
impl<T> Ship<T>{
pub fn get_enum(&self, index: usize) -> Option<RwLockReadGuard<'_, Container<T>>>{
self.content[index].read().ok()
}
// The below code fails to compile:
// pub fn get(&self, index: usize) -> Option<&T>{
// match self.content[index].borrow().ok().unwrap() {
// Container::Full(c) => Some(c),
// _=> None
// }
// }
pub fn get_mut(&mut self, index: usize) -> Option<&mut T>{
match self.content[index].get_mut().ok().unwrap() {
Container::Full(c) => Some(c),
_=> None
}
}
}
The above seem to compile, but is it safe code to run? I would also like to provide an interface for read-only access, but I failed to find the corresponding function in the API. For that what can be used?
It is certainly safe to run, after all Rust guarantees that if you don't use
unsafeit's memory and thread safe. But it most certainly doesn't do what you want it to, sinceget_mutrequires you to only have one reference to theRwLockbut in that case you could just forgo theRwLockalltogether and have the same effect, but that doesn't let you share aShipacross threads, it requires an exclusive reference.You likely want to use a
RwLockthat supportsmapping on it's guards such as the one fromparking_lot:Playground