I'm trying to create some kind of history manager system. Which would be able to redo and undo actions. I'm locking my road_manager
in my main loop. So that lock never expires. But then when I try to use my road_manager
again I have to lock it, which would result in a deadlock. How can I avoid this? I'm using lazy_static
so I can use my managers globally.
main.rs, where I define my manager variables:
lazy_static! {
pub static ref HISTORY_MANAGER: Mutex<managers::history::HistoryManager> =
Mutex::new(managers::history::HistoryManager::new());
pub static ref ROAD_MANAGER: RwLock<managers::road::RoadManager> =
RwLock::new(managers::road::RoadManager::new());
// There are and will be more managers, but they're unrelated
}
/// Returns the history manager
pub fn get_history_manager() -> &'static Mutex<managers::history::HistoryManager> {
&HISTORY_MANAGER
}
/// Returns the road manager
pub fn get_road_manager() -> &'static RwLock<managers::road::RoadManager> {
&ROAD_MANAGER
}
window.rs, my main loop where I lock road_manager
:
let mut road_manager = crate::get_road_manager().write().unwrap();
// road_manager gets used every frame, for things like writing and reading from the cache.
get_history_manager().lock().unwrap().undo(); // gets called whenever the undo button is pressed
Then, in my history manager—upon the undo function I'll have to use my road_manager
again. Which will not work since that'll result in a deadlock.
crate::get_road_manager().write().unwrap().destroy(road._id.unwrap()); // thread 'main' panicked at 'rwlock write lock would result in deadlock'
Full source code can be found here, for if you need more context.