Skip to main content

nuclei/sync/rwlock/
guards.rs

1//! The guards of a [`RwLock`]: the read and write guards, the guards that map
2//! to a component of the value, and their forms that keep the lock alive
3//! through an `Arc`.
4//!
5//! Every guard holds a pointer to the value (or to the component it was
6//! mapped to) next to the lock it releases, so mapping and downgrading never
7//! touch the lock: they only change which guard holds the release.
8
9#![allow(unsafe_code)]
10
11use core::fmt;
12use core::marker::PhantomData;
13use core::mem::ManuallyDrop;
14use core::ops::{Deref, DerefMut};
15use core::ptr;
16use std::sync::Arc;
17
18use super::RwLock;
19use crate::sync::raw_rwlock::RawRwLock;
20
21/// Shared access to a [`RwLock`]'s value, or to a component of it; releases
22/// on drop.
23///
24/// The release is one atomic read-modify-write when no waiter needs telling.
25/// Otherwise it is lock-free, not wait-free: it returns after one pass over
26/// the queue, plus at most one for each operation of another thread that
27/// lands on the queue meanwhile (see [Progress](crate::sync#progress)).
28#[must_use = "dropping the guard releases the lock at once"]
29pub struct RwLockReadGuard<'a, T: ?Sized> {
30    raw: &'a RawRwLock,
31    data: *const T,
32    marker: PhantomData<&'a T>,
33}
34
35// SAFETY: the guard is a shared reference to the component, and a read
36// excludes every writer for as long as it lives.
37unsafe impl<T: ?Sized + Sync> Send for RwLockReadGuard<'_, T> {}
38// SAFETY: as above.
39unsafe impl<T: ?Sized + Send + Sync> Sync for RwLockReadGuard<'_, T> {}
40
41impl<'a, T: ?Sized> RwLockReadGuard<'a, T> {
42    pub(super) fn new(lock: &'a RwLock<T>) -> Self {
43        Self {
44            raw: &lock.raw,
45            data: lock.value.get(),
46            marker: PhantomData,
47        }
48    }
49
50    /// The lock and component, once the guard is spent: releasing is left
51    /// to whoever takes it over.
52    fn into_parts(self) -> (&'a RawRwLock, *const T) {
53        let spent = ManuallyDrop::new(self);
54        (spent.raw, spent.data)
55    }
56
57    /// A guard for a component of the locked data. It cannot fail: this
58    /// guard already holds a read.
59    ///
60    /// An associated function, `RwLockReadGuard::map(guard, f)`: a method
61    /// would shadow methods of the locked data.
62    #[inline]
63    pub fn map<F, U>(this: Self, f: F) -> RwLockReadGuard<'a, U>
64    where
65        U: ?Sized,
66        F: FnOnce(&T) -> &U,
67    {
68        let data = ptr::from_ref(f(&*this));
69        let (raw, _) = this.into_parts();
70        RwLockReadGuard {
71            raw,
72            data,
73            marker: PhantomData,
74        }
75    }
76
77    /// [`map`](Self::map) that gives the guard back when `f` finds no
78    /// component, with the read still held.
79    #[inline]
80    pub fn try_map<F, U>(this: Self, f: F) -> Result<RwLockReadGuard<'a, U>, Self>
81    where
82        U: ?Sized,
83        F: FnOnce(&T) -> Option<&U>,
84    {
85        let data = match f(&*this) {
86            Some(data) => ptr::from_ref(data),
87            None => return Err(this),
88        };
89        let (raw, _) = this.into_parts();
90        Ok(RwLockReadGuard {
91            raw,
92            data,
93            marker: PhantomData,
94        })
95    }
96}
97
98impl<T: ?Sized> Deref for RwLockReadGuard<'_, T> {
99    type Target = T;
100
101    fn deref(&self) -> &T {
102        // SAFETY: a read excludes every writer, and `data` points into the
103        // value of the lock it holds.
104        unsafe { &*self.data }
105    }
106}
107
108impl<T: ?Sized> Drop for RwLockReadGuard<'_, T> {
109    fn drop(&mut self) {
110        self.raw.read_unlock();
111    }
112}
113
114impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLockReadGuard<'_, T> {
115    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116        fmt::Debug::fmt(&**self, f)
117    }
118}
119
120impl<T: ?Sized + fmt::Display> fmt::Display for RwLockReadGuard<'_, T> {
121    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122        fmt::Display::fmt(&**self, f)
123    }
124}
125
126/// Shared access to a [`RwLock`] held through an `Arc`, to its value or to
127/// a component `U` of it; releases on drop. The release makes the progress
128/// [`RwLockReadGuard`]'s does.
129#[must_use = "dropping the guard releases the lock at once"]
130pub struct OwnedRwLockReadGuard<T: ?Sized, U: ?Sized = T> {
131    lock: Arc<RwLock<T>>,
132    data: *const U,
133    _p: PhantomData<T>,
134}
135
136// SAFETY: the guard shares `&U`, and the lock it keeps alive can drop its
137// `T` on whichever thread drops the last `Arc`.
138unsafe impl<T: ?Sized + Send + Sync, U: ?Sized + Sync> Send for OwnedRwLockReadGuard<T, U> {}
139// SAFETY: as above.
140unsafe impl<T: ?Sized + Send + Sync, U: ?Sized + Send + Sync> Sync for OwnedRwLockReadGuard<T, U> {}
141
142impl<T: ?Sized> OwnedRwLockReadGuard<T> {
143    pub(super) fn new(lock: Arc<RwLock<T>>) -> Self {
144        Self {
145            data: lock.value.get(),
146            lock,
147            _p: PhantomData,
148        }
149    }
150}
151
152impl<T: ?Sized, U: ?Sized> OwnedRwLockReadGuard<T, U> {
153    /// The `Arc` and component, once the guard is spent: releasing is left
154    /// to whoever takes it over.
155    fn into_parts(self) -> (Arc<RwLock<T>>, *const U) {
156        let spent = ManuallyDrop::new(self);
157        // SAFETY: `spent` is never dropped, so this is the only read of the
158        // `Arc` and it is moved out exactly once.
159        (unsafe { ptr::read(&spent.lock) }, spent.data)
160    }
161
162    /// A guard for a component of the locked data. It cannot fail: this
163    /// guard already holds a read.
164    ///
165    /// An associated function, `OwnedRwLockReadGuard::map(guard, f)`: a
166    /// method would shadow methods of the locked data.
167    #[inline]
168    pub fn map<F, V>(this: Self, f: F) -> OwnedRwLockReadGuard<T, V>
169    where
170        V: ?Sized,
171        F: FnOnce(&U) -> &V,
172    {
173        let data = ptr::from_ref(f(&*this));
174        let (lock, _) = this.into_parts();
175        OwnedRwLockReadGuard {
176            lock,
177            data,
178            _p: PhantomData,
179        }
180    }
181
182    /// [`map`](Self::map) that gives the guard back when `f` finds no
183    /// component, with the read still held.
184    #[inline]
185    pub fn try_map<F, V>(this: Self, f: F) -> Result<OwnedRwLockReadGuard<T, V>, Self>
186    where
187        V: ?Sized,
188        F: FnOnce(&U) -> Option<&V>,
189    {
190        let data = match f(&*this) {
191            Some(data) => ptr::from_ref(data),
192            None => return Err(this),
193        };
194        let (lock, _) = this.into_parts();
195        Ok(OwnedRwLockReadGuard {
196            lock,
197            data,
198            _p: PhantomData,
199        })
200    }
201
202    /// The `Arc` of the lock this guard holds a read of.
203    #[inline]
204    pub fn rwlock(this: &Self) -> &Arc<RwLock<T>> {
205        &this.lock
206    }
207}
208
209impl<T: ?Sized, U: ?Sized> Deref for OwnedRwLockReadGuard<T, U> {
210    type Target = U;
211
212    fn deref(&self) -> &U {
213        // SAFETY: a read excludes every writer, and `data` points into the
214        // value of the lock it holds.
215        unsafe { &*self.data }
216    }
217}
218
219impl<T: ?Sized, U: ?Sized> Drop for OwnedRwLockReadGuard<T, U> {
220    fn drop(&mut self) {
221        self.lock.raw.read_unlock();
222    }
223}
224
225impl<T: ?Sized, U: ?Sized + fmt::Debug> fmt::Debug for OwnedRwLockReadGuard<T, U> {
226    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
227        fmt::Debug::fmt(&**self, f)
228    }
229}
230
231impl<T: ?Sized, U: ?Sized + fmt::Display> fmt::Display for OwnedRwLockReadGuard<T, U> {
232    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233        fmt::Display::fmt(&**self, f)
234    }
235}
236
237/// Exclusive access to a [`RwLock`]'s value; releases on drop. The release
238/// makes the progress [`RwLockReadGuard`]'s does.
239#[must_use = "dropping the guard releases the lock at once"]
240pub struct RwLockWriteGuard<'a, T: ?Sized> {
241    raw: &'a RawRwLock,
242    data: *mut T,
243    marker: PhantomData<&'a mut T>,
244}
245
246// SAFETY: the guard is a unique reference to the value, and the write
247// excludes every other guard for as long as it lives.
248unsafe impl<T: ?Sized + Send + Sync> Send for RwLockWriteGuard<'_, T> {}
249// SAFETY: as above, shared as a `&T`.
250unsafe impl<T: ?Sized + Send + Sync> Sync for RwLockWriteGuard<'_, T> {}
251
252impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
253    pub(super) fn new(lock: &'a RwLock<T>) -> Self {
254        Self {
255            raw: &lock.raw,
256            data: lock.value.get(),
257            marker: PhantomData,
258        }
259    }
260
261    /// The lock and value, once the guard is spent: releasing is left to
262    /// whoever takes it over.
263    fn into_parts(self) -> (&'a RawRwLock, *mut T) {
264        let spent = ManuallyDrop::new(self);
265        (spent.raw, spent.data)
266    }
267
268    /// A guard for a component of the locked data. It cannot fail: this
269    /// guard already holds the write.
270    ///
271    /// An associated function, `RwLockWriteGuard::map(guard, f)`: a method
272    /// would shadow methods of the locked data.
273    #[inline]
274    pub fn map<F, U>(mut this: Self, f: F) -> RwLockMappedWriteGuard<'a, U>
275    where
276        U: ?Sized,
277        F: FnOnce(&mut T) -> &mut U,
278    {
279        let data = ptr::from_mut(f(&mut *this));
280        let (raw, _) = this.into_parts();
281        RwLockMappedWriteGuard {
282            raw,
283            data,
284            marker: PhantomData,
285        }
286    }
287
288    /// A read guard for a component of the locked data, made while the
289    /// write is turned into a read in one step, as
290    /// [`downgrade`](Self::downgrade) does. Inside `f` the write is still
291    /// held, yet `f` is given only a `&T`: a `&mut T` could be kept past the
292    /// downgrade through interior mutability.
293    #[inline]
294    pub fn downgrade_map<F, U>(this: Self, f: F) -> RwLockReadGuard<'a, U>
295    where
296        U: ?Sized,
297        F: FnOnce(&T) -> &U,
298    {
299        let data = ptr::from_ref(f(&*this));
300        let (raw, _) = this.into_parts();
301        // The read guard exists before the step, so a panic out of it still
302        // releases the read the step made.
303        let guard = RwLockReadGuard {
304            raw,
305            data,
306            marker: PhantomData,
307        };
308        raw.downgrade();
309        guard
310    }
311
312    /// [`map`](Self::map) that gives the guard back when `f` finds no
313    /// component, with the write still held.
314    #[inline]
315    pub fn try_map<F, U>(mut this: Self, f: F) -> Result<RwLockMappedWriteGuard<'a, U>, Self>
316    where
317        U: ?Sized,
318        F: FnOnce(&mut T) -> Option<&mut U>,
319    {
320        let data = match f(&mut *this) {
321            Some(data) => ptr::from_mut(data),
322            None => return Err(this),
323        };
324        let (raw, _) = this.into_parts();
325        Ok(RwLockMappedWriteGuard {
326            raw,
327            data,
328            marker: PhantomData,
329        })
330    }
331
332    /// [`downgrade_map`](Self::downgrade_map) that gives the guard back when
333    /// `f` finds no component: the lock is then neither released nor
334    /// downgraded.
335    #[inline]
336    pub fn try_downgrade_map<F, U>(this: Self, f: F) -> Result<RwLockReadGuard<'a, U>, Self>
337    where
338        U: ?Sized,
339        F: FnOnce(&T) -> Option<&U>,
340    {
341        let data = match f(&*this) {
342            Some(data) => ptr::from_ref(data),
343            None => return Err(this),
344        };
345        let (raw, _) = this.into_parts();
346        let guard = RwLockReadGuard {
347            raw,
348            data,
349            marker: PhantomData,
350        };
351        raw.downgrade();
352        Ok(guard)
353    }
354
355    /// This guard as a [`RwLockMappedWriteGuard`], for a struct field that
356    /// holds one. The same as `RwLockWriteGuard::map(guard, |me| me)`.
357    #[inline]
358    pub fn into_mapped(this: Self) -> RwLockMappedWriteGuard<'a, T> {
359        Self::map(this, |me| me)
360    }
361
362    /// Turns the write into a read in one step, so no writer gets in
363    /// between.
364    ///
365    /// This does not necessarily let more readers in: a writer may be next
366    /// in line. The readers queued behind a writer-free front share the lock
367    /// now, and are woken to do so.
368    ///
369    /// It makes the progress a release does (see [`RwLockReadGuard`]).
370    ///
371    /// ```
372    /// use nuclei::sync::RwLock;
373    ///
374    /// let lock = RwLock::new(1);
375    /// let mut write = lock.try_write().expect("free");
376    /// *write += 1;
377    /// let read = write.downgrade();
378    /// assert_eq!(*read, 2);
379    /// assert!(lock.try_write().is_err(), "the read is still held");
380    /// assert!(lock.try_read().is_ok(), "readers share it");
381    /// ```
382    pub fn downgrade(self) -> RwLockReadGuard<'a, T> {
383        let (raw, data) = self.into_parts();
384        let guard = RwLockReadGuard {
385            raw,
386            data,
387            marker: PhantomData,
388        };
389        raw.downgrade();
390        guard
391    }
392}
393
394impl<T: ?Sized> Deref for RwLockWriteGuard<'_, T> {
395    type Target = T;
396
397    fn deref(&self) -> &T {
398        // SAFETY: the write excludes every other guard.
399        unsafe { &*self.data }
400    }
401}
402
403impl<T: ?Sized> DerefMut for RwLockWriteGuard<'_, T> {
404    fn deref_mut(&mut self) -> &mut T {
405        // SAFETY: as in `deref`, and `&mut self` makes this borrow unique.
406        unsafe { &mut *self.data }
407    }
408}
409
410impl<T: ?Sized> Drop for RwLockWriteGuard<'_, T> {
411    fn drop(&mut self) {
412        self.raw.write_unlock();
413    }
414}
415
416impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLockWriteGuard<'_, T> {
417    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
418        fmt::Debug::fmt(&**self, f)
419    }
420}
421
422impl<T: ?Sized + fmt::Display> fmt::Display for RwLockWriteGuard<'_, T> {
423    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
424        fmt::Display::fmt(&**self, f)
425    }
426}
427
428/// Exclusive access to a component of a [`RwLock`]'s value, made by
429/// [`RwLockWriteGuard::map`]; releases on drop. The release makes the
430/// progress [`RwLockReadGuard`]'s does.
431#[must_use = "dropping the guard releases the lock at once"]
432pub struct RwLockMappedWriteGuard<'a, T: ?Sized> {
433    raw: &'a RawRwLock,
434    data: *mut T,
435    marker: PhantomData<&'a mut T>,
436}
437
438// SAFETY: as for `RwLockWriteGuard`.
439unsafe impl<T: ?Sized + Send + Sync> Send for RwLockMappedWriteGuard<'_, T> {}
440// SAFETY: as for `RwLockWriteGuard`.
441unsafe impl<T: ?Sized + Send + Sync> Sync for RwLockMappedWriteGuard<'_, T> {}
442
443impl<'a, T: ?Sized> RwLockMappedWriteGuard<'a, T> {
444    /// The lock, once the guard is spent: releasing is left to whoever
445    /// takes it over.
446    fn into_raw(self) -> &'a RawRwLock {
447        ManuallyDrop::new(self).raw
448    }
449
450    /// A guard for a component of the component. It cannot fail: this guard
451    /// already holds the write.
452    ///
453    /// An associated function, `RwLockMappedWriteGuard::map(guard, f)`: a
454    /// method would shadow methods of the locked data.
455    #[inline]
456    pub fn map<F, U>(mut this: Self, f: F) -> RwLockMappedWriteGuard<'a, U>
457    where
458        U: ?Sized,
459        F: FnOnce(&mut T) -> &mut U,
460    {
461        let data = ptr::from_mut(f(&mut *this));
462        RwLockMappedWriteGuard {
463            raw: this.into_raw(),
464            data,
465            marker: PhantomData,
466        }
467    }
468
469    /// [`map`](Self::map) that gives the guard back when `f` finds no
470    /// component, with the write still held.
471    #[inline]
472    pub fn try_map<F, U>(mut this: Self, f: F) -> Result<RwLockMappedWriteGuard<'a, U>, Self>
473    where
474        U: ?Sized,
475        F: FnOnce(&mut T) -> Option<&mut U>,
476    {
477        let data = match f(&mut *this) {
478            Some(data) => ptr::from_mut(data),
479            None => return Err(this),
480        };
481        Ok(RwLockMappedWriteGuard {
482            raw: this.into_raw(),
483            data,
484            marker: PhantomData,
485        })
486    }
487}
488
489impl<T: ?Sized> Deref for RwLockMappedWriteGuard<'_, T> {
490    type Target = T;
491
492    fn deref(&self) -> &T {
493        // SAFETY: the write excludes every other guard, and `data` points
494        // into the value of the lock it holds.
495        unsafe { &*self.data }
496    }
497}
498
499impl<T: ?Sized> DerefMut for RwLockMappedWriteGuard<'_, T> {
500    fn deref_mut(&mut self) -> &mut T {
501        // SAFETY: as in `deref`, and `&mut self` makes this borrow unique.
502        unsafe { &mut *self.data }
503    }
504}
505
506impl<T: ?Sized> Drop for RwLockMappedWriteGuard<'_, T> {
507    fn drop(&mut self) {
508        self.raw.write_unlock();
509    }
510}
511
512impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLockMappedWriteGuard<'_, T> {
513    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
514        fmt::Debug::fmt(&**self, f)
515    }
516}
517
518impl<T: ?Sized + fmt::Display> fmt::Display for RwLockMappedWriteGuard<'_, T> {
519    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
520        fmt::Display::fmt(&**self, f)
521    }
522}
523
524/// Exclusive access to a [`RwLock`]'s value through an [`Arc`] the guard
525/// holds; releases on drop. Made by [`RwLock::write_owned`]. The release
526/// makes the progress [`RwLockReadGuard`]'s does.
527#[must_use = "dropping the guard releases the lock at once"]
528pub struct OwnedRwLockWriteGuard<T: ?Sized> {
529    lock: Arc<RwLock<T>>,
530    data: *mut T,
531    _p: PhantomData<T>,
532}
533
534// SAFETY: the guard is a unique reference to the value, and the write
535// excludes every other guard for as long as it lives.
536unsafe impl<T: ?Sized + Send + Sync> Send for OwnedRwLockWriteGuard<T> {}
537// SAFETY: as above, shared as a `&T`.
538unsafe impl<T: ?Sized + Send + Sync> Sync for OwnedRwLockWriteGuard<T> {}
539
540impl<T: ?Sized> OwnedRwLockWriteGuard<T> {
541    pub(super) fn new(lock: Arc<RwLock<T>>) -> Self {
542        Self {
543            data: lock.value.get(),
544            lock,
545            _p: PhantomData,
546        }
547    }
548
549    /// The `Arc` and value, once the guard is spent: releasing is left to
550    /// whoever takes it over.
551    fn into_parts(self) -> (Arc<RwLock<T>>, *mut T) {
552        let spent = ManuallyDrop::new(self);
553        // SAFETY: `spent` is never dropped, so this is the only read of the
554        // `Arc` and it is moved out exactly once.
555        (unsafe { ptr::read(&spent.lock) }, spent.data)
556    }
557
558    /// A guard for a component of the locked data. It cannot fail: this
559    /// guard already holds the write.
560    ///
561    /// An associated function, `OwnedRwLockWriteGuard::map(guard, f)`: a
562    /// method would shadow methods of the locked data.
563    #[inline]
564    pub fn map<F, U>(mut this: Self, f: F) -> OwnedRwLockMappedWriteGuard<T, U>
565    where
566        U: ?Sized,
567        F: FnOnce(&mut T) -> &mut U,
568    {
569        let data = ptr::from_mut(f(&mut *this));
570        let (lock, _) = this.into_parts();
571        OwnedRwLockMappedWriteGuard {
572            lock,
573            data,
574            _p: PhantomData,
575        }
576    }
577
578    /// A read guard for a component of the locked data, made while the
579    /// write is turned into a read in one step, as
580    /// [`downgrade`](Self::downgrade) does. Inside `f` the write is still
581    /// held, yet `f` is given only a `&T`: a `&mut T` could be kept past the
582    /// downgrade through interior mutability.
583    #[inline]
584    pub fn downgrade_map<F, U>(this: Self, f: F) -> OwnedRwLockReadGuard<T, U>
585    where
586        U: ?Sized,
587        F: FnOnce(&T) -> &U,
588    {
589        let data = ptr::from_ref(f(&*this));
590        let (lock, _) = this.into_parts();
591        let guard = OwnedRwLockReadGuard {
592            lock,
593            data,
594            _p: PhantomData,
595        };
596        guard.lock.raw.downgrade();
597        guard
598    }
599
600    /// [`map`](Self::map) that gives the guard back when `f` finds no
601    /// component, with the write still held.
602    #[inline]
603    pub fn try_map<F, U>(mut this: Self, f: F) -> Result<OwnedRwLockMappedWriteGuard<T, U>, Self>
604    where
605        U: ?Sized,
606        F: FnOnce(&mut T) -> Option<&mut U>,
607    {
608        let data = match f(&mut *this) {
609            Some(data) => ptr::from_mut(data),
610            None => return Err(this),
611        };
612        let (lock, _) = this.into_parts();
613        Ok(OwnedRwLockMappedWriteGuard {
614            lock,
615            data,
616            _p: PhantomData,
617        })
618    }
619
620    /// [`downgrade_map`](Self::downgrade_map) that gives the guard back when
621    /// `f` finds no component: the lock is then neither released nor
622    /// downgraded.
623    #[inline]
624    pub fn try_downgrade_map<F, U>(this: Self, f: F) -> Result<OwnedRwLockReadGuard<T, U>, Self>
625    where
626        U: ?Sized,
627        F: FnOnce(&T) -> Option<&U>,
628    {
629        let data = match f(&*this) {
630            Some(data) => ptr::from_ref(data),
631            None => return Err(this),
632        };
633        let (lock, _) = this.into_parts();
634        let guard = OwnedRwLockReadGuard {
635            lock,
636            data,
637            _p: PhantomData,
638        };
639        guard.lock.raw.downgrade();
640        Ok(guard)
641    }
642
643    /// This guard as an [`OwnedRwLockMappedWriteGuard`], for a struct field
644    /// that holds one. The same as `OwnedRwLockWriteGuard::map(guard, |me|
645    /// me)`.
646    #[inline]
647    pub fn into_mapped(this: Self) -> OwnedRwLockMappedWriteGuard<T> {
648        Self::map(this, |me| me)
649    }
650
651    /// Turns the write into a read in one step, so no writer gets in
652    /// between. See [`RwLockWriteGuard::downgrade`].
653    pub fn downgrade(self) -> OwnedRwLockReadGuard<T> {
654        let (lock, data) = self.into_parts();
655        let guard = OwnedRwLockReadGuard {
656            lock,
657            data,
658            _p: PhantomData,
659        };
660        guard.lock.raw.downgrade();
661        guard
662    }
663
664    /// The `Arc` of the lock this guard holds the write of.
665    #[inline]
666    pub fn rwlock(this: &Self) -> &Arc<RwLock<T>> {
667        &this.lock
668    }
669}
670
671impl<T: ?Sized> Deref for OwnedRwLockWriteGuard<T> {
672    type Target = T;
673
674    fn deref(&self) -> &T {
675        // SAFETY: the write excludes every other guard.
676        unsafe { &*self.data }
677    }
678}
679
680impl<T: ?Sized> DerefMut for OwnedRwLockWriteGuard<T> {
681    fn deref_mut(&mut self) -> &mut T {
682        // SAFETY: as in `deref`, and `&mut self` makes this borrow unique.
683        unsafe { &mut *self.data }
684    }
685}
686
687impl<T: ?Sized> Drop for OwnedRwLockWriteGuard<T> {
688    fn drop(&mut self) {
689        self.lock.raw.write_unlock();
690    }
691}
692
693impl<T: ?Sized + fmt::Debug> fmt::Debug for OwnedRwLockWriteGuard<T> {
694    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
695        fmt::Debug::fmt(&**self, f)
696    }
697}
698
699impl<T: ?Sized + fmt::Display> fmt::Display for OwnedRwLockWriteGuard<T> {
700    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
701        fmt::Display::fmt(&**self, f)
702    }
703}
704
705/// Exclusive access to a component `U` of the value of a [`RwLock<T>`] held
706/// through an `Arc`, made by [`OwnedRwLockWriteGuard::map`]; releases on
707/// drop. The release makes the progress [`RwLockReadGuard`]'s does.
708#[must_use = "dropping the guard releases the lock at once"]
709pub struct OwnedRwLockMappedWriteGuard<T: ?Sized, U: ?Sized = T> {
710    lock: Arc<RwLock<T>>,
711    data: *mut U,
712    _p: PhantomData<T>,
713}
714
715// SAFETY: as for `OwnedRwLockWriteGuard`.
716unsafe impl<T: ?Sized + Send + Sync, U: ?Sized + Send + Sync> Send
717    for OwnedRwLockMappedWriteGuard<T, U>
718{
719}
720// SAFETY: as for `OwnedRwLockWriteGuard`.
721unsafe impl<T: ?Sized + Send + Sync, U: ?Sized + Send + Sync> Sync
722    for OwnedRwLockMappedWriteGuard<T, U>
723{
724}
725
726impl<T: ?Sized, U: ?Sized> OwnedRwLockMappedWriteGuard<T, U> {
727    /// The `Arc`, once the guard is spent: releasing is left to whoever
728    /// takes it over.
729    fn into_lock(self) -> Arc<RwLock<T>> {
730        let spent = ManuallyDrop::new(self);
731        // SAFETY: `spent` is never dropped, so this is the only read of the
732        // `Arc` and it is moved out exactly once.
733        unsafe { ptr::read(&spent.lock) }
734    }
735
736    /// A guard for a component of the component. It cannot fail: this guard
737    /// already holds the write.
738    ///
739    /// An associated function, `OwnedRwLockMappedWriteGuard::map(guard, f)`:
740    /// a method would shadow methods of the locked data.
741    #[inline]
742    pub fn map<V, F>(mut this: Self, f: F) -> OwnedRwLockMappedWriteGuard<T, V>
743    where
744        V: ?Sized,
745        F: FnOnce(&mut U) -> &mut V,
746    {
747        let data = ptr::from_mut(f(&mut *this));
748        OwnedRwLockMappedWriteGuard {
749            lock: this.into_lock(),
750            data,
751            _p: PhantomData,
752        }
753    }
754
755    /// [`map`](Self::map) that gives the guard back when `f` finds no
756    /// component, with the write still held.
757    #[inline]
758    pub fn try_map<V, F>(mut this: Self, f: F) -> Result<OwnedRwLockMappedWriteGuard<T, V>, Self>
759    where
760        V: ?Sized,
761        F: FnOnce(&mut U) -> Option<&mut V>,
762    {
763        let data = match f(&mut *this) {
764            Some(data) => ptr::from_mut(data),
765            None => return Err(this),
766        };
767        Ok(OwnedRwLockMappedWriteGuard {
768            lock: this.into_lock(),
769            data,
770            _p: PhantomData,
771        })
772    }
773
774    /// The `Arc` of the lock this guard holds the write of.
775    #[inline]
776    pub fn rwlock(this: &Self) -> &Arc<RwLock<T>> {
777        &this.lock
778    }
779}
780
781impl<T: ?Sized, U: ?Sized> Deref for OwnedRwLockMappedWriteGuard<T, U> {
782    type Target = U;
783
784    fn deref(&self) -> &U {
785        // SAFETY: the write excludes every other guard, and `data` points
786        // into the value of the lock it holds.
787        unsafe { &*self.data }
788    }
789}
790
791impl<T: ?Sized, U: ?Sized> DerefMut for OwnedRwLockMappedWriteGuard<T, U> {
792    fn deref_mut(&mut self) -> &mut U {
793        // SAFETY: as in `deref`, and `&mut self` makes this borrow unique.
794        unsafe { &mut *self.data }
795    }
796}
797
798impl<T: ?Sized, U: ?Sized> Drop for OwnedRwLockMappedWriteGuard<T, U> {
799    fn drop(&mut self) {
800        self.lock.raw.write_unlock();
801    }
802}
803
804impl<T: ?Sized, U: ?Sized + fmt::Debug> fmt::Debug for OwnedRwLockMappedWriteGuard<T, U> {
805    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
806        fmt::Debug::fmt(&**self, f)
807    }
808}
809
810impl<T: ?Sized, U: ?Sized + fmt::Display> fmt::Display for OwnedRwLockMappedWriteGuard<T, U> {
811    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
812        fmt::Display::fmt(&**self, f)
813    }
814}