os_trait/
mutex.rs

1use crate::mutex_traits::{ConstInit, RawMutex};
2cfg_if::cfg_if! {
3    if #[cfg(all(feature = "std", not(feature = "std-custom-mutex")))] {
4        pub use std_impl::BlockingMutex;
5    } else {
6        pub use mutex::BlockingMutex;
7    }
8}
9
10/// A fake mutex is for testing.
11/// It does not provide any synchronization between threads,
12#[derive(Default)]
13pub struct FakeRawMutex {}
14
15impl FakeRawMutex {
16    /// Create a new `FakeRawMutex`.
17    pub const fn new() -> Self {
18        Self {}
19    }
20}
21
22unsafe impl Send for FakeRawMutex {}
23
24impl ConstInit for FakeRawMutex {
25    const INIT: Self = Self::new();
26}
27
28unsafe impl RawMutex for FakeRawMutex {
29    type GuardMarker = *mut ();
30
31    #[inline]
32    fn lock(&self) {}
33
34    #[inline]
35    fn try_lock(&self) -> bool {
36        true
37    }
38
39    #[inline]
40    unsafe fn unlock(&self) {}
41
42    #[inline]
43    fn is_locked(&self) -> bool {
44        true
45    }
46}
47
48#[cfg(feature = "std")]
49#[allow(dead_code)]
50mod std_impl {
51    use core::marker::PhantomData;
52    use mutex_traits::RawMutex;
53    use std::sync::MutexGuard;
54
55    /// A wrap of [`std::sync::Mutex`]. This type's purpose is to allow choosing
56    /// between using [`std::sync::Mutex`] or `BlockingMutex` through feature flags.
57    pub struct BlockingMutex<R: RawMutex, T> {
58        mutex: std::sync::Mutex<T>,
59        _marker: PhantomData<R>,
60    }
61
62    impl<R: RawMutex, T> BlockingMutex<R, T> {
63        /// Creates a new `Mutex`.
64        #[inline]
65        pub const fn new(val: T) -> BlockingMutex<R, T> {
66            Self {
67                mutex: std::sync::Mutex::new(val),
68                _marker: PhantomData,
69            }
70        }
71
72        /// lock
73        #[inline]
74        pub fn lock(&self) -> MutexGuard<'_, T> {
75            self.mutex.lock().unwrap()
76        }
77
78        /// try_lock
79        #[inline]
80        pub fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
81            self.mutex.try_lock().ok()
82        }
83
84        /// try_with_lock
85        #[must_use]
86        #[inline]
87        pub fn with_lock<U>(&self, f: impl FnOnce(&mut T) -> U) -> U {
88            let mut guard = self.mutex.lock().unwrap();
89            f(&mut *guard)
90        }
91
92        /// try_with_lock
93        #[must_use]
94        #[inline]
95        pub fn try_with_lock<U>(&self, f: impl FnOnce(&mut T) -> U) -> Option<U> {
96            let mut guard = self.try_lock()?;
97            Some(f(&mut *guard))
98        }
99    }
100}