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