]>
Commit | Line | Data |
---|---|---|
532ac7d7 | 1 | use crate::sys::mutex as imp; |
1a4d82fc | 2 | |
1b1a35ee XL |
3 | /// An OS-based mutual exclusion lock, meant for use in static variables. |
4 | /// | |
5 | /// This mutex has a const constructor ([`StaticMutex::new`]), does not | |
29967ef6 | 6 | /// implement `Drop` to cleanup resources, and causes UB when used reentrantly. |
1b1a35ee XL |
7 | /// |
8 | /// This mutex does not implement poisoning. | |
1a4d82fc | 9 | /// |
1b1a35ee XL |
10 | /// This is a wrapper around `imp::Mutex` that does *not* call `init()` and |
11 | /// `destroy()`. | |
12 | pub struct StaticMutex(imp::Mutex); | |
1a4d82fc | 13 | |
1b1a35ee | 14 | unsafe impl Sync for StaticMutex {} |
1a4d82fc | 15 | |
1b1a35ee | 16 | impl StaticMutex { |
62682a34 | 17 | /// Creates a new mutex for use. |
1b1a35ee XL |
18 | pub const fn new() -> Self { |
19 | Self(imp::Mutex::new()) | |
dfeec247 | 20 | } |
62682a34 | 21 | |
1b1a35ee XL |
22 | /// Calls raw_lock() and then returns an RAII guard to guarantee the mutex |
23 | /// will be unlocked. | |
3157f602 | 24 | /// |
29967ef6 XL |
25 | /// It is undefined behaviour to call this function while locked by the |
26 | /// same thread. | |
3157f602 | 27 | #[inline] |
29967ef6 | 28 | pub unsafe fn lock(&'static self) -> StaticMutexGuard { |
1b1a35ee XL |
29 | self.0.lock(); |
30 | StaticMutexGuard(&self.0) | |
dfeec247 | 31 | } |
1b1a35ee | 32 | } |
3157f602 | 33 | |
1b1a35ee | 34 | #[must_use] |
29967ef6 | 35 | pub struct StaticMutexGuard(&'static imp::Mutex); |
1b1a35ee | 36 | |
29967ef6 | 37 | impl Drop for StaticMutexGuard { |
1a4d82fc | 38 | #[inline] |
1b1a35ee XL |
39 | fn drop(&mut self) { |
40 | unsafe { | |
41 | self.0.unlock(); | |
42 | } | |
dfeec247 | 43 | } |
1b1a35ee | 44 | } |
94b46f34 | 45 | |
1b1a35ee XL |
46 | /// An OS-based mutual exclusion lock. |
47 | /// | |
48 | /// This mutex does *not* have a const constructor, cleans up its resources in | |
49 | /// its `Drop` implementation, may safely be moved (when not borrowed), and | |
50 | /// does not cause UB when used reentrantly. | |
51 | /// | |
52 | /// This mutex does not implement poisoning. | |
53 | /// | |
29967ef6 XL |
54 | /// This is either a wrapper around `Box<imp::Mutex>` or `imp::Mutex`, |
55 | /// depending on the platform. It is boxed on platforms where `imp::Mutex` may | |
56 | /// not be moved. | |
57 | pub struct MovableMutex(imp::MovableMutex); | |
1b1a35ee XL |
58 | |
59 | unsafe impl Sync for MovableMutex {} | |
60 | ||
61 | impl MovableMutex { | |
62 | /// Creates a new mutex. | |
63 | pub fn new() -> Self { | |
29967ef6 | 64 | let mut mutex = imp::MovableMutex::from(imp::Mutex::new()); |
1b1a35ee XL |
65 | unsafe { mutex.init() }; |
66 | Self(mutex) | |
67 | } | |
68 | ||
29967ef6 | 69 | pub(super) fn raw(&self) -> &imp::Mutex { |
1b1a35ee XL |
70 | &self.0 |
71 | } | |
72 | ||
73 | /// Locks the mutex blocking the current thread until it is available. | |
94b46f34 | 74 | #[inline] |
1b1a35ee XL |
75 | pub fn raw_lock(&self) { |
76 | unsafe { self.0.lock() } | |
94b46f34 | 77 | } |
1a4d82fc | 78 | |
9346a6ac | 79 | /// Attempts to lock the mutex without blocking, returning whether it was |
1a4d82fc | 80 | /// successfully acquired or not. |
1a4d82fc | 81 | #[inline] |
1b1a35ee XL |
82 | pub fn try_lock(&self) -> bool { |
83 | unsafe { self.0.try_lock() } | |
dfeec247 | 84 | } |
1a4d82fc | 85 | |
9346a6ac | 86 | /// Unlocks the mutex. |
1a4d82fc JJ |
87 | /// |
88 | /// Behavior is undefined if the current thread does not actually hold the | |
89 | /// mutex. | |
90 | #[inline] | |
dfeec247 XL |
91 | pub unsafe fn raw_unlock(&self) { |
92 | self.0.unlock() | |
93 | } | |
1a4d82fc JJ |
94 | } |
95 | ||
1b1a35ee | 96 | impl Drop for MovableMutex { |
94b46f34 | 97 | fn drop(&mut self) { |
1b1a35ee | 98 | unsafe { self.0.destroy() }; |
94b46f34 XL |
99 | } |
100 | } |