]> git.lizzy.rs Git - rust.git/blob - library/std/src/sys_common/mutex.rs
Rollup merge of #96173 - jmaargh:jmaargh/with-capacity-doc-fix, r=Dylan-DPC
[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 cleans up its resources in its `Drop` implementation, may safely
50 /// be moved (when not borrowed), and does not cause UB when used reentrantly.
51 ///
52 /// This mutex does not implement poisoning.
53 ///
54 /// This is either a wrapper around `LazyBox<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);
58
59 unsafe impl Sync for MovableMutex {}
60
61 impl MovableMutex {
62     /// Creates a new mutex.
63     #[inline]
64     pub const fn new() -> Self {
65         Self(imp::MovableMutex::new())
66     }
67
68     pub(super) fn raw(&self) -> &imp::Mutex {
69         &self.0
70     }
71
72     /// Locks the mutex blocking the current thread until it is available.
73     #[inline]
74     pub fn raw_lock(&self) {
75         unsafe { self.0.lock() }
76     }
77
78     /// Attempts to lock the mutex without blocking, returning whether it was
79     /// successfully acquired or not.
80     #[inline]
81     pub fn try_lock(&self) -> bool {
82         unsafe { self.0.try_lock() }
83     }
84
85     /// Unlocks the mutex.
86     ///
87     /// Behavior is undefined if the current thread does not actually hold the
88     /// mutex.
89     #[inline]
90     pub unsafe fn raw_unlock(&self) {
91         self.0.unlock()
92     }
93 }