est_render/utils/
arcmut.rs

1use std::{
2    sync::{Arc, Mutex},
3    time::{Duration, Instant},
4};
5
6#[derive(Debug, Clone)]
7pub struct ArcMut<T> {
8    inner: Arc<Mutex<T>>,
9}
10
11impl<T> ArcMut<T> {
12    pub fn new(value: T) -> ArcMut<T> {
13        ArcMut {
14            inner: Arc::new(Mutex::new(value)),
15        }
16    }
17
18    pub fn clone(&self) -> ArcMut<T> {
19        ArcMut {
20            inner: self.inner.clone(),
21        }
22    }
23
24    pub fn lock(&self) -> std::sync::MutexGuard<T> {
25        self.inner.lock().unwrap()
26    }
27
28    pub fn try_lock(&self) -> Option<std::sync::MutexGuard<T>> {
29        self.inner.try_lock().ok()
30    }
31
32    pub fn wait_borrow(&self) -> std::sync::MutexGuard<T> {
33        #[cfg(any(debug_assertions, feature = "enable-release-validation"))]
34        let start = Instant::now();
35
36        loop {
37            if let Ok(borrow) = self.inner.try_lock() {
38                return borrow;
39            }
40
41            #[cfg(any(debug_assertions, feature = "enable-release-validation"))]
42            if start.elapsed() > Duration::from_secs(5) {
43                panic!("wait_borrow: waited more than 5 seconds to acquire borrow");
44            }
45        }
46    }
47}
48
49pub mod hasher {
50    use super::ArcMut;
51    use std::{
52        hash::{Hash, Hasher},
53        sync::Arc,
54    };
55
56    impl<T: Hash> Hash for ArcMut<T> {
57        fn hash<H: Hasher>(&self, state: &mut H) {
58            let ptr = Arc::as_ptr(&self.inner);
59            ptr.hash(state);
60        }
61    }
62}