]> git.proxmox.com Git - rustc.git/blame - library/std/src/sys_common/mutex.rs
New upstream version 1.53.0+dfsg1
[rustc.git] / library / std / src / sys_common / mutex.rs
CommitLineData
532ac7d7 1use 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()`.
12pub struct StaticMutex(imp::Mutex);
1a4d82fc 13
1b1a35ee 14unsafe impl Sync for StaticMutex {}
1a4d82fc 15
1b1a35ee 16impl 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 35pub struct StaticMutexGuard(&'static imp::Mutex);
1b1a35ee 36
29967ef6 37impl 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.
57pub struct MovableMutex(imp::MovableMutex);
1b1a35ee
XL
58
59unsafe impl Sync for MovableMutex {}
60
61impl 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 96impl Drop for MovableMutex {
94b46f34 97 fn drop(&mut self) {
1b1a35ee 98 unsafe { self.0.destroy() };
94b46f34
XL
99 }
100}