Skip to main content

mermaid_cli/utils/
mutex_ext.rs

1use std::sync::{Arc, Mutex};
2use tracing::warn;
3
4/// Extension trait for Mutex to provide safe lock operations
5pub trait MutexExt<T> {
6    /// Lock the mutex, recovering from poison errors
7    /// This is safer than unwrap() as it handles poisoned mutexes gracefully
8    fn lock_safe(&self) -> T
9    where
10        T: Clone;
11
12    /// Lock the mutex for mutation, recovering from poison errors
13    fn lock_mut_safe(&self) -> std::sync::MutexGuard<'_, T>;
14}
15
16impl<T: Clone> MutexExt<T> for Mutex<T> {
17    fn lock_safe(&self) -> T {
18        match self.lock() {
19            Ok(guard) => guard.clone(),
20            Err(poisoned) => {
21                // Mutex was poisoned due to a panic in another thread
22                // We can still access the data, but we log the issue
23                warn!("Mutex was poisoned, recovering data");
24                poisoned.into_inner().clone()
25            },
26        }
27    }
28
29    fn lock_mut_safe(&self) -> std::sync::MutexGuard<'_, T> {
30        match self.lock() {
31            Ok(guard) => guard,
32            Err(poisoned) => {
33                // Mutex was poisoned, but we can still get the guard
34                warn!("Mutex was poisoned, recovering guard");
35                poisoned.into_inner()
36            },
37        }
38    }
39}
40
41/// Safe lock for Arc<Mutex<T>> - standalone function since we can't impl on Arc
42pub fn lock_arc_mutex_safe<T>(mutex: &Arc<Mutex<T>>) -> std::sync::MutexGuard<'_, T> {
43    match mutex.lock() {
44        Ok(guard) => guard,
45        Err(poisoned) => {
46            warn!("Arc<Mutex> was poisoned, recovering guard");
47            poisoned.into_inner()
48        },
49    }
50}
51
52/// Helper to lock a mutex with expect-style error message
53#[macro_export]
54macro_rules! lock_or_panic {
55    ($mutex:expr, $msg:expr) => {
56        $mutex.lock().unwrap_or_else(|e| {
57            panic!("{}: mutex poisoned: {}", $msg, e);
58        })
59    };
60}
61