1 | use std::fmt; |
2 | use std::future::Future; |
3 | use std::mem::ManuallyDrop; |
4 | use std::pin::Pin; |
5 | use std::sync::Arc; |
6 | use std::task::{Context, Poll}; |
7 | |
8 | use super::raw::{RawRead, RawUpgradableRead, RawUpgrade, RawWrite}; |
9 | use super::{ |
10 | RwLock, RwLockReadGuard, RwLockReadGuardArc, RwLockUpgradableReadGuard, |
11 | RwLockUpgradableReadGuardArc, RwLockWriteGuard, RwLockWriteGuardArc, |
12 | }; |
13 | |
14 | /// The future returned by [`RwLock::read`]. |
15 | pub struct Read<'a, T: ?Sized> { |
16 | /// Raw read lock acquisition future, doesn't depend on `T`. |
17 | pub(super) raw: RawRead<'a>, |
18 | |
19 | /// Pointer to the value protected by the lock. Covariant in `T`. |
20 | pub(super) value: *const T, |
21 | } |
22 | |
23 | unsafe impl<T: Sync + ?Sized> Send for Read<'_, T> {} |
24 | unsafe impl<T: Sync + ?Sized> Sync for Read<'_, T> {} |
25 | |
26 | impl<T: ?Sized> fmt::Debug for Read<'_, T> { |
27 | #[inline ] |
28 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
29 | f.write_str(data:"Read { .. }" ) |
30 | } |
31 | } |
32 | |
33 | impl<T: ?Sized> Unpin for Read<'_, T> {} |
34 | |
35 | impl<'a, T: ?Sized> Future for Read<'a, T> { |
36 | type Output = RwLockReadGuard<'a, T>; |
37 | |
38 | #[inline ] |
39 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
40 | ready!(Pin::new(&mut self.raw).poll(cx)); |
41 | |
42 | Poll::Ready(RwLockReadGuard { |
43 | lock: self.raw.lock, |
44 | value: self.value, |
45 | }) |
46 | } |
47 | } |
48 | |
49 | /// The future returned by [`RwLock::read_arc`]. |
50 | pub struct ReadArc<'a, T> { |
51 | /// Raw read lock acquisition future, doesn't depend on `T`. |
52 | pub(super) raw: RawRead<'a>, |
53 | |
54 | // FIXME: Could be covariant in T |
55 | pub(super) lock: &'a Arc<RwLock<T>>, |
56 | } |
57 | |
58 | unsafe impl<T: Send + Sync> Send for ReadArc<'_, T> {} |
59 | unsafe impl<T: Send + Sync> Sync for ReadArc<'_, T> {} |
60 | |
61 | impl<T> fmt::Debug for ReadArc<'_, T> { |
62 | #[inline ] |
63 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
64 | f.write_str(data:"ReadArc { .. }" ) |
65 | } |
66 | } |
67 | |
68 | impl<T> Unpin for ReadArc<'_, T> {} |
69 | |
70 | impl<'a, T> Future for ReadArc<'a, T> { |
71 | type Output = RwLockReadGuardArc<T>; |
72 | |
73 | #[inline ] |
74 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
75 | ready!(Pin::new(&mut self.raw).poll(cx)); |
76 | |
77 | // SAFETY: we just acquired a read lock |
78 | Poll::Ready(unsafe { RwLockReadGuardArc::from_arc(self.lock.clone()) }) |
79 | } |
80 | } |
81 | |
82 | /// The future returned by [`RwLock::upgradable_read`]. |
83 | pub struct UpgradableRead<'a, T: ?Sized> { |
84 | /// Raw upgradable read lock acquisition future, doesn't depend on `T`. |
85 | pub(super) raw: RawUpgradableRead<'a>, |
86 | |
87 | /// Pointer to the value protected by the lock. Invariant in `T` |
88 | /// as the upgradable lock could provide write access. |
89 | pub(super) value: *mut T, |
90 | } |
91 | |
92 | unsafe impl<T: Send + Sync + ?Sized> Send for UpgradableRead<'_, T> {} |
93 | unsafe impl<T: Sync + ?Sized> Sync for UpgradableRead<'_, T> {} |
94 | |
95 | impl<T: ?Sized> fmt::Debug for UpgradableRead<'_, T> { |
96 | #[inline ] |
97 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
98 | f.write_str(data:"UpgradableRead { .. }" ) |
99 | } |
100 | } |
101 | |
102 | impl<T: ?Sized> Unpin for UpgradableRead<'_, T> {} |
103 | |
104 | impl<'a, T: ?Sized> Future for UpgradableRead<'a, T> { |
105 | type Output = RwLockUpgradableReadGuard<'a, T>; |
106 | |
107 | #[inline ] |
108 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
109 | ready!(Pin::new(&mut self.raw).poll(cx)); |
110 | |
111 | Poll::Ready(RwLockUpgradableReadGuard { |
112 | lock: self.raw.lock, |
113 | value: self.value, |
114 | }) |
115 | } |
116 | } |
117 | |
118 | /// The future returned by [`RwLock::upgradable_read_arc`]. |
119 | pub struct UpgradableReadArc<'a, T: ?Sized> { |
120 | /// Raw upgradable read lock acquisition future, doesn't depend on `T`. |
121 | pub(super) raw: RawUpgradableRead<'a>, |
122 | |
123 | pub(super) lock: &'a Arc<RwLock<T>>, |
124 | } |
125 | |
126 | unsafe impl<T: Send + Sync + ?Sized> Send for UpgradableReadArc<'_, T> {} |
127 | unsafe impl<T: Send + Sync + ?Sized> Sync for UpgradableReadArc<'_, T> {} |
128 | |
129 | impl<T: ?Sized> fmt::Debug for UpgradableReadArc<'_, T> { |
130 | #[inline ] |
131 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
132 | f.write_str(data:"UpgradableReadArc { .. }" ) |
133 | } |
134 | } |
135 | |
136 | impl<T: ?Sized> Unpin for UpgradableReadArc<'_, T> {} |
137 | |
138 | impl<'a, T: ?Sized> Future for UpgradableReadArc<'a, T> { |
139 | type Output = RwLockUpgradableReadGuardArc<T>; |
140 | |
141 | #[inline ] |
142 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
143 | ready!(Pin::new(&mut self.raw).poll(cx)); |
144 | Poll::Ready(RwLockUpgradableReadGuardArc { |
145 | lock: self.lock.clone(), |
146 | }) |
147 | } |
148 | } |
149 | |
150 | /// The future returned by [`RwLock::write`]. |
151 | pub struct Write<'a, T: ?Sized> { |
152 | /// Raw write lock acquisition future, doesn't depend on `T`. |
153 | pub(super) raw: RawWrite<'a>, |
154 | |
155 | /// Pointer to the value protected by the lock. Invariant in `T`. |
156 | pub(super) value: *mut T, |
157 | } |
158 | |
159 | unsafe impl<T: Send + ?Sized> Send for Write<'_, T> {} |
160 | unsafe impl<T: Sync + ?Sized> Sync for Write<'_, T> {} |
161 | |
162 | impl<T: ?Sized> fmt::Debug for Write<'_, T> { |
163 | #[inline ] |
164 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
165 | f.write_str(data:"Write { .. }" ) |
166 | } |
167 | } |
168 | |
169 | impl<T: ?Sized> Unpin for Write<'_, T> {} |
170 | |
171 | impl<'a, T: ?Sized> Future for Write<'a, T> { |
172 | type Output = RwLockWriteGuard<'a, T>; |
173 | |
174 | #[inline ] |
175 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
176 | ready!(Pin::new(&mut self.raw).poll(cx)); |
177 | |
178 | Poll::Ready(RwLockWriteGuard { |
179 | lock: self.raw.lock, |
180 | value: self.value, |
181 | }) |
182 | } |
183 | } |
184 | |
185 | /// The future returned by [`RwLock::write_arc`]. |
186 | pub struct WriteArc<'a, T: ?Sized> { |
187 | /// Raw write lock acquisition future, doesn't depend on `T`. |
188 | pub(super) raw: RawWrite<'a>, |
189 | |
190 | pub(super) lock: &'a Arc<RwLock<T>>, |
191 | } |
192 | |
193 | unsafe impl<T: Send + Sync + ?Sized> Send for WriteArc<'_, T> {} |
194 | unsafe impl<T: Send + Sync + ?Sized> Sync for WriteArc<'_, T> {} |
195 | |
196 | impl<T: ?Sized> fmt::Debug for WriteArc<'_, T> { |
197 | #[inline ] |
198 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
199 | f.write_str(data:"WriteArc { .. }" ) |
200 | } |
201 | } |
202 | |
203 | impl<T: ?Sized> Unpin for WriteArc<'_, T> {} |
204 | |
205 | impl<'a, T: ?Sized> Future for WriteArc<'a, T> { |
206 | type Output = RwLockWriteGuardArc<T>; |
207 | |
208 | #[inline ] |
209 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
210 | ready!(Pin::new(&mut self.raw).poll(cx)); |
211 | |
212 | Poll::Ready(RwLockWriteGuardArc { |
213 | lock: self.lock.clone(), |
214 | }) |
215 | } |
216 | } |
217 | |
218 | /// The future returned by [`RwLockUpgradableReadGuard::upgrade`]. |
219 | pub struct Upgrade<'a, T: ?Sized> { |
220 | /// Raw read lock upgrade future, doesn't depend on `T`. |
221 | pub(super) raw: RawUpgrade<'a>, |
222 | |
223 | /// Pointer to the value protected by the lock. Invariant in `T`. |
224 | pub(super) value: *mut T, |
225 | } |
226 | |
227 | unsafe impl<T: Send + ?Sized> Send for Upgrade<'_, T> {} |
228 | unsafe impl<T: Sync + ?Sized> Sync for Upgrade<'_, T> {} |
229 | |
230 | impl<T: ?Sized> fmt::Debug for Upgrade<'_, T> { |
231 | #[inline ] |
232 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
233 | f.debug_struct(name:"Upgrade" ).finish() |
234 | } |
235 | } |
236 | |
237 | impl<T: ?Sized> Unpin for Upgrade<'_, T> {} |
238 | |
239 | impl<'a, T: ?Sized> Future for Upgrade<'a, T> { |
240 | type Output = RwLockWriteGuard<'a, T>; |
241 | |
242 | #[inline ] |
243 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
244 | let lock: &RawRwLock = ready!(Pin::new(&mut self.raw).poll(cx)); |
245 | |
246 | Poll::Ready(RwLockWriteGuard { |
247 | lock, |
248 | value: self.value, |
249 | }) |
250 | } |
251 | } |
252 | |
253 | /// The future returned by [`RwLockUpgradableReadGuardArc::upgrade`]. |
254 | pub struct UpgradeArc<T: ?Sized> { |
255 | /// Raw read lock upgrade future, doesn't depend on `T`. |
256 | /// `'static` is a lie, this field is actually referencing the |
257 | /// `Arc` data. But since this struct also stores said `Arc`, we know |
258 | /// this value will be alive as long as the struct is. |
259 | /// |
260 | /// Yes, one field of the `ArcUpgrade` struct is referencing another. |
261 | /// Such self-references are usually not sound without pinning. |
262 | /// However, in this case, there is an indirection via the heap; |
263 | /// moving the `ArcUpgrade` won't move the heap allocation of the `Arc`, |
264 | /// so the reference inside `RawUpgrade` isn't invalidated. |
265 | pub(super) raw: ManuallyDrop<RawUpgrade<'static>>, |
266 | |
267 | /// Pointer to the value protected by the lock. Invariant in `T`. |
268 | pub(super) lock: ManuallyDrop<Arc<RwLock<T>>>, |
269 | } |
270 | |
271 | impl<T: ?Sized> fmt::Debug for UpgradeArc<T> { |
272 | #[inline ] |
273 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
274 | f.debug_struct(name:"ArcUpgrade" ).finish() |
275 | } |
276 | } |
277 | |
278 | impl<T: ?Sized> Unpin for UpgradeArc<T> {} |
279 | |
280 | impl<T: ?Sized> Future for UpgradeArc<T> { |
281 | type Output = RwLockWriteGuardArc<T>; |
282 | |
283 | #[inline ] |
284 | fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
285 | ready!(Pin::new(&mut *self.raw).poll(cx)); |
286 | |
287 | Poll::Ready(RwLockWriteGuardArc { |
288 | lock: unsafe { ManuallyDrop::take(&mut self.lock) }, |
289 | }) |
290 | } |
291 | } |
292 | |
293 | impl<T: ?Sized> Drop for UpgradeArc<T> { |
294 | #[inline ] |
295 | fn drop(&mut self) { |
296 | if !self.raw.is_ready() { |
297 | // SAFETY: we drop the `Arc` (decrementing the reference count) |
298 | // only if this future was cancelled before returning an |
299 | // upgraded lock. |
300 | unsafe { |
301 | ManuallyDrop::drop(&mut self.raw); |
302 | ManuallyDrop::drop(&mut self.lock); |
303 | }; |
304 | } |
305 | } |
306 | } |
307 | |