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