]> git.proxmox.com Git - rustc.git/blob - library/std/src/sys_common/rwlock.rs
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / library / std / src / sys_common / rwlock.rs
1 use crate::sys::rwlock as imp;
2
3 /// An OS-based reader-writer lock.
4 ///
5 /// This structure is entirely unsafe and serves as the lowest layer of a
6 /// cross-platform binding of system rwlocks. It is recommended to use the
7 /// safer types at the top level of this crate instead of this type.
8 pub struct RWLock(imp::RWLock);
9
10 impl RWLock {
11 /// Creates a new reader-writer lock for use.
12 ///
13 /// Behavior is undefined if the reader-writer lock is moved after it is
14 /// first used with any of the functions below.
15 pub const fn new() -> RWLock {
16 RWLock(imp::RWLock::new())
17 }
18
19 /// Acquires shared access to the underlying lock, blocking the current
20 /// thread to do so.
21 ///
22 /// Behavior is undefined if the rwlock has been moved between this and any
23 /// previous method call.
24 #[inline]
25 pub unsafe fn read(&self) {
26 self.0.read()
27 }
28
29 /// Attempts to acquire shared access to this lock, returning whether it
30 /// succeeded or not.
31 ///
32 /// This function does not block the current thread.
33 ///
34 /// Behavior is undefined if the rwlock has been moved between this and any
35 /// previous method call.
36 #[inline]
37 pub unsafe fn try_read(&self) -> bool {
38 self.0.try_read()
39 }
40
41 /// Acquires write access to the underlying lock, blocking the current thread
42 /// to do so.
43 ///
44 /// Behavior is undefined if the rwlock has been moved between this and any
45 /// previous method call.
46 #[inline]
47 pub unsafe fn write(&self) {
48 self.0.write()
49 }
50
51 /// Attempts to acquire exclusive access to this lock, returning whether it
52 /// succeeded or not.
53 ///
54 /// This function does not block the current thread.
55 ///
56 /// Behavior is undefined if the rwlock has been moved between this and any
57 /// previous method call.
58 #[inline]
59 pub unsafe fn try_write(&self) -> bool {
60 self.0.try_write()
61 }
62
63 /// Unlocks previously acquired shared access to this lock.
64 ///
65 /// Behavior is undefined if the current thread does not have shared access.
66 #[inline]
67 pub unsafe fn read_unlock(&self) {
68 self.0.read_unlock()
69 }
70
71 /// Unlocks previously acquired exclusive access to this lock.
72 ///
73 /// Behavior is undefined if the current thread does not currently have
74 /// exclusive access.
75 #[inline]
76 pub unsafe fn write_unlock(&self) {
77 self.0.write_unlock()
78 }
79
80 /// Destroys OS-related resources with this RWLock.
81 ///
82 /// Behavior is undefined if there are any currently active users of this
83 /// lock.
84 #[inline]
85 pub unsafe fn destroy(&self) {
86 self.0.destroy()
87 }
88 }
89
90 // the cfg annotations only exist due to dead code warnings. the code itself is portable
91 #[cfg(unix)]
92 pub struct StaticRWLock(RWLock);
93
94 #[cfg(unix)]
95 impl StaticRWLock {
96 pub const fn new() -> StaticRWLock {
97 StaticRWLock(RWLock::new())
98 }
99
100 /// Acquires shared access to the underlying lock, blocking the current
101 /// thread to do so.
102 ///
103 /// The lock is automatically unlocked when the returned guard is dropped.
104 #[inline]
105 pub fn read_with_guard(&'static self) -> RWLockReadGuard {
106 // SAFETY: All methods require static references, therefore self
107 // cannot be moved between invocations.
108 unsafe {
109 self.0.read();
110 }
111 RWLockReadGuard(&self.0)
112 }
113
114 /// Acquires write access to the underlying lock, blocking the current thread
115 /// to do so.
116 ///
117 /// The lock is automatically unlocked when the returned guard is dropped.
118 #[inline]
119 pub fn write_with_guard(&'static self) -> RWLockWriteGuard {
120 // SAFETY: All methods require static references, therefore self
121 // cannot be moved between invocations.
122 unsafe {
123 self.0.write();
124 }
125 RWLockWriteGuard(&self.0)
126 }
127 }
128
129 #[cfg(unix)]
130 pub struct RWLockReadGuard(&'static RWLock);
131
132 #[cfg(unix)]
133 impl Drop for RWLockReadGuard {
134 fn drop(&mut self) {
135 unsafe { self.0.read_unlock() }
136 }
137 }
138
139 #[cfg(unix)]
140 pub struct RWLockWriteGuard(&'static RWLock);
141
142 #[cfg(unix)]
143 impl Drop for RWLockWriteGuard {
144 fn drop(&mut self) {
145 unsafe { self.0.write_unlock() }
146 }
147 }