]> git.lizzy.rs Git - rust.git/blob - library/std/src/sys_common/rwlock.rs
Auto merge of #85690 - bstrie:m2_arena, r=jackh726,nagisa
[rust.git] / library / std / src / sys_common / rwlock.rs
1 use crate::sys::rwlock as imp;
2
3 /// An OS-based reader-writer lock, meant for use in static variables.
4 ///
5 /// This rwlock does not implement poisoning.
6 ///
7 /// This rwlock has a const constructor ([`StaticRWLock::new`]), does not
8 /// implement `Drop` to cleanup resources.
9 pub struct StaticRWLock(imp::RWLock);
10
11 impl StaticRWLock {
12     /// Creates a new rwlock for use.
13     pub const fn new() -> Self {
14         Self(imp::RWLock::new())
15     }
16
17     /// Acquires shared access to the underlying lock, blocking the current
18     /// thread to do so.
19     ///
20     /// The lock is automatically unlocked when the returned guard is dropped.
21     #[inline]
22     pub fn read(&'static self) -> StaticRWLockReadGuard {
23         unsafe { self.0.read() };
24         StaticRWLockReadGuard(&self.0)
25     }
26
27     /// Acquires write access to the underlying lock, blocking the current thread
28     /// to do so.
29     ///
30     /// The lock is automatically unlocked when the returned guard is dropped.
31     #[inline]
32     pub fn write(&'static self) -> StaticRWLockWriteGuard {
33         unsafe { self.0.write() };
34         StaticRWLockWriteGuard(&self.0)
35     }
36 }
37
38 #[must_use]
39 pub struct StaticRWLockReadGuard(&'static imp::RWLock);
40
41 impl Drop for StaticRWLockReadGuard {
42     #[inline]
43     fn drop(&mut self) {
44         unsafe {
45             self.0.read_unlock();
46         }
47     }
48 }
49
50 #[must_use]
51 pub struct StaticRWLockWriteGuard(&'static imp::RWLock);
52
53 impl Drop for StaticRWLockWriteGuard {
54     #[inline]
55     fn drop(&mut self) {
56         unsafe {
57             self.0.write_unlock();
58         }
59     }
60 }
61
62 /// An OS-based reader-writer lock.
63 ///
64 /// This rwlock does *not* have a const constructor, cleans up its resources in
65 /// its `Drop` implementation and may safely be moved (when not borrowed).
66 ///
67 /// This rwlock does not implement poisoning.
68 ///
69 /// This is either a wrapper around `Box<imp::RWLock>` or `imp::RWLock`,
70 /// depending on the platform. It is boxed on platforms where `imp::RWLock` may
71 /// not be moved.
72 pub struct MovableRWLock(imp::MovableRWLock);
73
74 impl MovableRWLock {
75     /// Creates a new reader-writer lock for use.
76     pub fn new() -> Self {
77         Self(imp::MovableRWLock::from(imp::RWLock::new()))
78     }
79
80     /// Acquires shared access to the underlying lock, blocking the current
81     /// thread to do so.
82     #[inline]
83     pub fn read(&self) {
84         unsafe { self.0.read() }
85     }
86
87     /// Attempts to acquire shared access to this lock, returning whether it
88     /// succeeded or not.
89     ///
90     /// This function does not block the current thread.
91     #[inline]
92     pub fn try_read(&self) -> bool {
93         unsafe { self.0.try_read() }
94     }
95
96     /// Acquires write access to the underlying lock, blocking the current thread
97     /// to do so.
98     #[inline]
99     pub fn write(&self) {
100         unsafe { self.0.write() }
101     }
102
103     /// Attempts to acquire exclusive access to this lock, returning whether it
104     /// succeeded or not.
105     ///
106     /// This function does not block the current thread.
107     #[inline]
108     pub fn try_write(&self) -> bool {
109         unsafe { self.0.try_write() }
110     }
111
112     /// Unlocks previously acquired shared access to this lock.
113     ///
114     /// Behavior is undefined if the current thread does not have shared access.
115     #[inline]
116     pub unsafe fn read_unlock(&self) {
117         self.0.read_unlock()
118     }
119
120     /// Unlocks previously acquired exclusive access to this lock.
121     ///
122     /// Behavior is undefined if the current thread does not currently have
123     /// exclusive access.
124     #[inline]
125     pub unsafe fn write_unlock(&self) {
126         self.0.write_unlock()
127     }
128 }
129
130 impl Drop for MovableRWLock {
131     fn drop(&mut self) {
132         unsafe { self.0.destroy() };
133     }
134 }