rwlock.rs - source
Description: Source of the Rust file `library/std/src/sync/poison/rwlock.rs`.

#
std/sync/poison/
rwlock.rs

    1use crate::cell::UnsafeCell;
    2use crate::fmt;
    3use crate::marker::PhantomData;
    4use crate::mem::{self, ManuallyDrop, forget};
    5use crate::ops::{Deref, DerefMut};
    6use crate::ptr::NonNull;
    7use crate::sync::{LockResult, PoisonError, TryLockError, TryLockResult, poison};
    8use crate::sys::sync as sys;
    9
    10/// A reader-writer lock
    11///
    12/// This type of lock allows a number of readers or at most one writer at any
    13/// point in time. The write portion of this lock typically allows modification
    14/// of the underlying data (exclusive access) and the read portion of this lock
    15/// typically allows for read-only access (shared access).
    16///
    17/// In comparison, a [`Mutex`] does not distinguish between readers or writers
    18/// that acquire the lock, therefore blocking any threads waiting for the lock to
    19/// become available. An `RwLock` will allow any number of readers to acquire the
    20/// lock as long as a writer is not holding the lock.
    21///
    22/// The priority policy of the lock is dependent on the underlying operating
    23/// system's implementation, and this type does not guarantee that any
    24/// particular policy will be used. In particular, a writer which is waiting to
    25/// acquire the lock in `write` might or might not block concurrent calls to
    26/// `read`, e.g.:
    27///
    28/// <details><summary>Potential deadlock example</summary>
    29///
    30/// ```text
    31/// // Thread 1              |  // Thread 2
    32/// let _rg1 = lock.read();  |
    33///                          |  // will block
    34///                          |  let _wg = lock.write();
    35/// // may deadlock          |
    36/// let _rg2 = lock.read();  |
    37/// ```
    38///
    39/// </details>
    40///
    41/// The type parameter `T` represents the data that this lock protects. It is
    42/// required that `T` satisfies [`Send`] to be shared across threads and
    43/// [`Sync`] to allow concurrent access through readers. The RAII guards
    44/// returned from the locking methods implement [`Deref`] (and [`DerefMut`]
    45/// for the `write` methods) to allow access to the content of the lock.
    46///
    47/// # Poisoning
    48///
    49/// An `RwLock`, like [`Mutex`], will [usually] become poisoned on a panic. Note,
    50/// however, that an `RwLock` may only be poisoned if a panic occurs while it is
    51/// locked exclusively (write mode). If a panic occurs in any reader, then the
    52/// lock will not be poisoned.
    53///
    54/// [usually]: super::Mutex#poisoning
    55///
    56/// # Examples
    57///
    58/// ```
    59/// use std::sync::RwLock;
    60///
    61/// let lock = RwLock::new(5);
    62///
    63/// // many reader locks can be held at once
    64/// {
    65///     let r1 = lock.read().unwrap();
    66///     let r2 = lock.read().unwrap();
    67///     assert_eq!(*r1, 5);
    68///     assert_eq!(*r2, 5);
    69/// } // read locks are dropped at this point
    70///
    71/// // only one write lock may be held, however
    72/// {
    73///     let mut w = lock.write().unwrap();
    74///     *w += 1;
    75///     assert_eq!(*w, 6);
    76/// } // write lock is dropped here
    77/// ```
    78///
    79/// [`Mutex`]: super::Mutex
    80#[stable(feature = "rust1", since = "1.0.0")]
    81#[cfg_attr(not(test), rustc_diagnostic_item = "RwLock")]
    82pub struct RwLock<T: ?Sized> {
    83    /// The inner [`sys::RwLock`] that synchronizes thread access to the protected data.
    84    inner: sys::RwLock,
    85    /// A flag denoting if this `RwLock` has been poisoned.
    86    poison: poison::Flag,
    87    /// The lock-protected data.
    88    data: UnsafeCell<T>,
    89}
    90
    91#[stable(feature = "rust1", since = "1.0.0")]
    92unsafe impl<T: ?Sized + Send> Send for RwLock<T> {}
    93
    94#[stable(feature = "rust1", since = "1.0.0")]
    95unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
    96
    97////////////////////////////////////////////////////////////////////////////////////////////////////
    98// Guards
    99////////////////////////////////////////////////////////////////////////////////////////////////////
    100
    101/// RAII structure used to release the shared read access of a lock when
    102/// dropped.
    103///
    104/// This structure is created by the [`read`] and [`try_read`] methods on
    105/// [`RwLock`].
    106///
    107/// [`read`]: RwLock::read
    108/// [`try_read`]: RwLock::try_read
    109#[must_use = "if unused the RwLock will immediately unlock"]
    110#[must_not_suspend = "holding a RwLockReadGuard across suspend \
    111                      points can cause deadlocks, delays, \
    112                      and cause Futures to not implement `Send`"]
    113#[stable(feature = "rust1", since = "1.0.0")]
    114#[clippy::has_significant_drop]
    115#[cfg_attr(not(test), rustc_diagnostic_item = "RwLockReadGuard")]
    116pub struct RwLockReadGuard<'rwlock, T: ?Sized + 'rwlock> {
    117    /// A pointer to the data protected by the `RwLock`. Note that we use a pointer here instead of
    118    /// `&'rwlock T` to avoid `noalias` violations, because a `RwLockReadGuard` instance only holds
    119    /// immutability until it drops, not for its whole scope.
    120    /// `NonNull` is preferable over `*const T` to allow for niche optimizations. `NonNull` is also
    121    /// covariant over `T`, just like we would have with `&T`.
    122    data: NonNull<T>,
    123    /// A reference to the internal [`sys::RwLock`] that we have read-locked.
    124    inner_lock: &'rwlock sys::RwLock,
    125}
    126
    127#[stable(feature = "rust1", since = "1.0.0")]
    128impl<T: ?Sized> !Send for RwLockReadGuard<'_, T> {}
    129
    130#[stable(feature = "rwlock_guard_sync", since = "1.23.0")]
    131unsafe impl<T: ?Sized + Sync> Sync for RwLockReadGuard<'_, T> {}
    132
    133/// RAII structure used to release the exclusive write access of a lock when
    134/// dropped.
    135///
    136/// This structure is created by the [`write`] and [`try_write`] methods
    137/// on [`RwLock`].
    138///
    139/// [`write`]: RwLock::write
    140/// [`try_write`]: RwLock::try_write
    141#[must_use = "if unused the RwLock will immediately unlock"]
    142#[must_not_suspend = "holding a RwLockWriteGuard across suspend \
    143                      points can cause deadlocks, delays, \
    144                      and cause Future's to not implement `Send`"]
    145#[stable(feature = "rust1", since = "1.0.0")]
    146#[clippy::has_significant_drop]
    147#[cfg_attr(not(test), rustc_diagnostic_item = "RwLockWriteGuard")]
    148pub struct RwLockWriteGuard<'rwlock, T: ?Sized + 'rwlock> {
    149    /// A reference to the [`RwLock`] that we have write-locked.
    150    lock: &'rwlock RwLock<T>,
    151    /// The poison guard. See the [`poison`] module for more information.
    152    poison: poison::Guard,
    153}
    154
    155#[stable(feature = "rust1", since = "1.0.0")]
    156impl<T: ?Sized> !Send for RwLockWriteGuard<'_, T> {}
    157
    158#[stable(feature = "rwlock_guard_sync", since = "1.23.0")]
    159unsafe impl<T: ?Sized + Sync> Sync for RwLockWriteGuard<'_, T> {}
    160
    161/// RAII structure used to release the shared read access of a lock when
    162/// dropped, which can point to a subfield of the protected data.
    163///
    164/// This structure is created by the [`map`] and [`filter_map`] methods
    165/// on [`RwLockReadGuard`].
    166///
    167/// [`map`]: RwLockReadGuard::map
    168/// [`filter_map`]: RwLockReadGuard::filter_map
    169#[must_use = "if unused the RwLock will immediately unlock"]
    170#[must_not_suspend = "holding a MappedRwLockReadGuard across suspend \
    171                      points can cause deadlocks, delays, \
    172                      and cause Futures to not implement `Send`"]
    173#[unstable(feature = "mapped_lock_guards", issue = "117108")]
    174#[clippy::has_significant_drop]
    175pub struct MappedRwLockReadGuard<'rwlock, T: ?Sized + 'rwlock> {
    176    /// A pointer to the data protected by the `RwLock`. Note that we use a pointer here instead of
    177    /// `&'rwlock T` to avoid `noalias` violations, because a `MappedRwLockReadGuard` instance only
    178    /// holds immutability until it drops, not for its whole scope.
    179    /// `NonNull` is preferable over `*const T` to allow for niche optimizations. `NonNull` is also
    180    /// covariant over `T`, just like we would have with `&T`.
    181    data: NonNull<T>,
    182    /// A reference to the internal [`sys::RwLock`] that we have read-locked.
    183    inner_lock: &'rwlock sys::RwLock,
    184}
    185
    186#[unstable(feature = "mapped_lock_guards", issue = "117108")]
    187impl<T: ?Sized> !Send for MappedRwLockReadGuard<'_, T> {}
    188
    189#[unstable(feature = "mapped_lock_guards", issue = "117108")]
    190unsafe impl<T: ?Sized + Sync> Sync for MappedRwLockReadGuard<'_, T> {}
    191
    192/// RAII structure used to release the exclusive write access of a lock when
    193/// dropped, which can point to a subfield of the protected data.
    194///
    195/// This structure is created by the [`map`] and [`filter_map`] methods
    196/// on [`RwLockWriteGuard`].
    197///
    198/// [`map`]: RwLockWriteGuard::map
    199/// [`filter_map`]: RwLockWriteGuard::filter_map
    200#[must_use = "if unused the RwLock will immediately unlock"]
    201#[must_not_suspend = "holding a MappedRwLockWriteGuard across suspend \
    202                      points can cause deadlocks, delays, \
    203                      and cause Future's to not implement `Send`"]
    204#[unstable(feature = "mapped_lock_guards", issue = "117108")]
    205#[clippy::has_significant_drop]
    206pub struct MappedRwLockWriteGuard<'rwlock, T: ?Sized + 'rwlock> {
    207    /// A pointer to the data protected by the `RwLock`. Note that we use a pointer here instead of
    208    /// `&'rwlock T` to avoid `noalias` violations, because a `MappedRwLockWriteGuard` instance only
    209    /// holds uniquneness until it drops, not for its whole scope.
    210    /// `NonNull` is preferable over `*const T` to allow for niche optimizations.
    211    data: NonNull<T>,
    212    /// `NonNull` is covariant over `T`, so we add a `PhantomData<&'rwlock mut T>` field here to
    213    /// enforce the correct invariance over `T`.
    214    _variance: PhantomData<&'rwlock mut T>,
    215    /// A reference to the internal [`sys::RwLock`] that we have write-locked.
    216    inner_lock: &'rwlock sys::RwLock,
    217    /// A reference to the original `RwLock`'s poison state.
    218    poison_flag: &'rwlock poison::Flag,
    219    /// The poison guard. See the [`poison`] module for more information.
    220    poison_guard: poison::Guard,
    221}
    222
    223#[unstable(feature = "mapped_lock_guards", issue = "117108")]
    224impl<T: ?Sized> !Send for MappedRwLockWriteGuard<'_, T> {}
    225
    226#[unstable(feature = "mapped_lock_guards", issue = "117108")]
    227unsafe impl<T: ?Sized + Sync> Sync for MappedRwLockWriteGuard<'_, T> {}
    228
    229////////////////////////////////////////////////////////////////////////////////////////////////////
    230// Implementations
    231////////////////////////////////////////////////////////////////////////////////////////////////////
    232
    233impl<T> RwLock<T> {
    234    /// Creates a new instance of an `RwLock<T>` which is unlocked.
    235    ///
    236    /// # Examples
    237    ///
    238    /// ```
    239    /// use std::sync::RwLock;
    240    ///
    241    /// let lock = RwLock::new(5);
    242    /// ```
    243    #[stable(feature = "rust1", since = "1.0.0")]
    244    #[rustc_const_stable(feature = "const_locks", since = "1.63.0")]
    245    #[inline]
    246    pub const fn new(t: T) -> RwLock<T> {
    247        RwLock { inner: sys::RwLock::new(), poison: poison::Flag::new(), data: UnsafeCell::new(t) }
    248    }
    249
    250    /// Returns the contained value by cloning it.
    251    ///
    252    /// # Errors
    253    ///
    254    /// This function will return an error if the `RwLock` is poisoned. An
    255    /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
    256    /// lock.
    257    ///
    258    /// # Examples
    259    ///
    260    /// ```
    261    /// #![feature(lock_value_accessors)]
    262    ///
    263    /// use std::sync::RwLock;
    264    ///
    265    /// let mut lock = RwLock::new(7);
    266    ///
    267    /// assert_eq!(lock.get_cloned().unwrap(), 7);
    268    /// ```
    269    #[unstable(feature = "lock_value_accessors", issue = "133407")]
    270    pub fn get_cloned(&self) -> Result<T, PoisonError<()>>
    271    where
    272        T: Clone,
    273    {
    274        match self.read() {
    275            Ok(guard) => Ok((*guard).clone()),
    276            Err(_) => Err(PoisonError::new(())),
    277        }
    278    }
    279
    280    /// Sets the contained value.
    281    ///
    282    /// # Errors
    283    ///
    284    /// This function will return an error containing the provided `value` if
    285    /// the `RwLock` is poisoned. An `RwLock` is poisoned whenever a writer
    286    /// panics while holding an exclusive lock.
    287    ///
    288    /// # Examples
    289    ///
    290    /// ```
    291    /// #![feature(lock_value_accessors)]
    292    ///
    293    /// use std::sync::RwLock;
    294    ///
    295    /// let mut lock = RwLock::new(7);
    296    ///
    297    /// assert_eq!(lock.get_cloned().unwrap(), 7);
    298    /// lock.set(11).unwrap();
    299    /// assert_eq!(lock.get_cloned().unwrap(), 11);
    300    /// ```
    301    #[unstable(feature = "lock_value_accessors", issue = "133407")]
    302    #[rustc_should_not_be_called_on_const_items]
    303    pub fn set(&self, value: T) -> Result<(), PoisonError<T>> {
    304        if mem::needs_drop::<T>() {
    305            // If the contained value has non-trivial destructor, we
    306            // call that destructor after the lock being released.
    307            self.replace(value).map(drop)
    308        } else {
    309            match self.write() {
    310                Ok(mut guard) => {
    311                    *guard = value;
    312
    313                    Ok(())
    314                }
    315                Err(_) => Err(PoisonError::new(value)),
    316            }
    317        }
    318    }
    319
    320    /// Replaces the contained value with `value`, and returns the old contained value.
    321    ///
    322    /// # Errors
    323    ///
    324    /// This function will return an error containing the provided `value` if
    325    /// the `RwLock` is poisoned. An `RwLock` is poisoned whenever a writer
    326    /// panics while holding an exclusive lock.
    327    ///
    328    /// # Examples
    329    ///
    330    /// ```
    331    /// #![feature(lock_value_accessors)]
    332    ///
    333    /// use std::sync::RwLock;
    334    ///
    335    /// let mut lock = RwLock::new(7);
    336    ///
    337    /// assert_eq!(lock.replace(11).unwrap(), 7);
    338    /// assert_eq!(lock.get_cloned().unwrap(), 11);
    339    /// ```
    340    #[unstable(feature = "lock_value_accessors", issue = "133407")]
    341    #[rustc_should_not_be_called_on_const_items]
    342    pub fn replace(&self, value: T) -> LockResult<T> {
    343        match self.write() {
    344            Ok(mut guard) => Ok(mem::replace(&mut *guard, value)),
    345            Err(_) => Err(PoisonError::new(value)),
    346        }
    347    }
    348}
    349
    350impl<T: ?Sized> RwLock<T> {
    351    /// Locks this `RwLock` with shared read access, blocking the current thread
    352    /// until it can be acquired.
    353    ///
    354    /// The calling thread will be blocked until there are no more writers which
    355    /// hold the lock. There may be other readers currently inside the lock when
    356    /// this method returns. This method does not provide any guarantees with
    357    /// respect to the ordering of whether contentious readers or writers will
    358    /// acquire the lock first.
    359    ///
    360    /// Returns an RAII guard which will release this thread's shared access
    361    /// once it is dropped.
    362    ///
    363    /// # Errors
    364    ///
    365    /// This function will return an error if the `RwLock` is poisoned. An
    366    /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
    367    /// lock. The failure will occur immediately after the lock has been
    368    /// acquired. The acquired lock guard will be contained in the returned
    369    /// error.
    370    ///
    371    /// # Panics
    372    ///
    373    /// This function might panic when called if the lock is already held by the current thread.
    374    ///
    375    /// # Examples
    376    ///
    377    /// ```
    378    /// use std::sync::{Arc, RwLock};
    379    /// use std::thread;
    380    ///
    381    /// let lock = Arc::new(RwLock::new(1));
    382    /// let c_lock = Arc::clone(&lock);
    383    ///
    384    /// let n = lock.read().unwrap();
    385    /// assert_eq!(*n, 1);
    386    ///
    387    /// thread::spawn(move || {
    388    ///     let r = c_lock.read();
    389    ///     assert!(r.is_ok());
    390    /// }).join().unwrap();
    391    /// ```
    392    #[inline]
    393    #[stable(feature = "rust1", since = "1.0.0")]
    394    #[rustc_should_not_be_called_on_const_items]
    395    pub fn read(&self) -> LockResult<RwLockReadGuard<'_, T>> {
    396        unsafe {
    397            self.inner.read();
    398            RwLockReadGuard::new(self)
    399        }
    400    }
    401
    402    /// Attempts to acquire this `RwLock` with shared read access.
    403    ///
    404    /// If the access could not be granted at this time, then `Err` is returned.
    405    /// Otherwise, an RAII guard is returned which will release the shared access
    406    /// when it is dropped.
    407    ///
    408    /// This function does not block.
    409    ///
    410    /// This function does not provide any guarantees with respect to the ordering
    411    /// of whether contentious readers or writers will acquire the lock first.
    412    ///
    413    /// # Errors
    414    ///
    415    /// This function will return the [`Poisoned`] error if the `RwLock` is
    416    /// poisoned. An `RwLock` is poisoned whenever a writer panics while holding
    417    /// an exclusive lock. `Poisoned` will only be returned if the lock would
    418    /// have otherwise been acquired. An acquired lock guard will be contained
    419    /// in the returned error.
    420    ///
    421    /// This function will return the [`WouldBlock`] error if the `RwLock` could
    422    /// not be acquired because it was already locked exclusively.
    423    ///
    424    /// [`Poisoned`]: TryLockError::Poisoned
    425    /// [`WouldBlock`]: TryLockError::WouldBlock
    426    ///
    427    /// # Examples
    428    ///
    429    /// ```
    430    /// use std::sync::RwLock;
    431    ///
    432    /// let lock = RwLock::new(1);
    433    ///
    434    /// match lock.try_read() {
    435    ///     Ok(n) => assert_eq!(*n, 1),
    436    ///     Err(_) => unreachable!(),
    437    /// };
    438    /// ```
    439    #[inline]
    440    #[stable(feature = "rust1", since = "1.0.0")]
    441    #[rustc_should_not_be_called_on_const_items]
    442    pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<'_, T>> {
    443        unsafe {
    444            if self.inner.try_read() {
    445                Ok(RwLockReadGuard::new(self)?)
    446            } else {
    447                Err(TryLockError::WouldBlock)
    448            }
    449        }
    450    }
    451
    452    /// Locks this `RwLock` with exclusive write access, blocking the current
    453    /// thread until it can be acquired.
    454    ///
    455    /// This function will not return while other writers or other readers
    456    /// currently have access to the lock.
    457    ///
    458    /// Returns an RAII guard which will drop the write access of this `RwLock`
    459    /// when dropped.
    460    ///
    461    /// # Errors
    462    ///
    463    /// This function will return an error if the `RwLock` is poisoned. An
    464    /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
    465    /// lock. An error will be returned when the lock is acquired. The acquired
    466    /// lock guard will be contained in the returned error.
    467    ///
    468    /// # Panics
    469    ///
    470    /// This function might panic when called if the lock is already held by the current thread.
    471    ///
    472    /// # Examples
    473    ///
    474    /// ```
    475    /// use std::sync::RwLock;
    476    ///
    477    /// let lock = RwLock::new(1);
    478    ///
    479    /// let mut n = lock.write().unwrap();
    480    /// *n = 2;
    481    ///
    482    /// assert!(lock.try_read().is_err());
    483    /// ```
    484    #[inline]
    485    #[stable(feature = "rust1", since = "1.0.0")]
    486    #[rustc_should_not_be_called_on_const_items]
    487    pub fn write(&self) -> LockResult<RwLockWriteGuard<'_, T>> {
    488        unsafe {
    489            self.inner.write();
    490            RwLockWriteGuard::new(self)
    491        }
    492    }
    493
    494    /// Attempts to lock this `RwLock` with exclusive write access.
    495    ///
    496    /// If the lock could not be acquired at this time, then `Err` is returned.
    497    /// Otherwise, an RAII guard is returned which will release the lock when
    498    /// it is dropped.
    499    ///
    500    /// This function does not block.
    501    ///
    502    /// This function does not provide any guarantees with respect to the ordering
    503    /// of whether contentious readers or writers will acquire the lock first.
    504    ///
    505    /// # Errors
    506    ///
    507    /// This function will return the [`Poisoned`] error if the `RwLock` is
    508    /// poisoned. An `RwLock` is poisoned whenever a writer panics while holding
    509    /// an exclusive lock. `Poisoned` will only be returned if the lock would
    510    /// have otherwise been acquired. An acquired lock guard will be contained
    511    /// in the returned error.
    512    ///
    513    /// This function will return the [`WouldBlock`] error if the `RwLock` could
    514    /// not be acquired because it was already locked.
    515    ///
    516    /// [`Poisoned`]: TryLockError::Poisoned
    517    /// [`WouldBlock`]: TryLockError::WouldBlock
    518    ///
    519    ///
    520    /// # Examples
    521    ///
    522    /// ```
    523    /// use std::sync::RwLock;
    524    ///
    525    /// let lock = RwLock::new(1);
    526    ///
    527    /// let n = lock.read().unwrap();
    528    /// assert_eq!(*n, 1);
    529    ///
    530    /// assert!(lock.try_write().is_err());
    531    /// ```
    532    #[inline]
    533    #[stable(feature = "rust1", since = "1.0.0")]
    534    #[rustc_should_not_be_called_on_const_items]
    535    pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<'_, T>> {
    536        unsafe {
    537            if self.inner.try_write() {
    538                Ok(RwLockWriteGuard::new(self)?)
    539            } else {
    540                Err(TryLockError::WouldBlock)
    541            }
    542        }
    543    }
    544
    545    /// Determines whether the lock is poisoned.
    546    ///
    547    /// If another thread is active, the lock can still become poisoned at any
    548    /// time. You should not trust a `false` value for program correctness
    549    /// without additional synchronization.
    550    ///
    551    /// # Examples
    552    ///
    553    /// ```
    554    /// use std::sync::{Arc, RwLock};
    555    /// use std::thread;
    556    ///
    557    /// let lock = Arc::new(RwLock::new(0));
    558    /// let c_lock = Arc::clone(&lock);
    559    ///
    560    /// let _ = thread::spawn(move || {
    561    ///     let _lock = c_lock.write().unwrap();
    562    ///     panic!(); // the lock gets poisoned
    563    /// }).join();
    564    /// assert_eq!(lock.is_poisoned(), true);
    565    /// ```
    566    #[inline]
    567    #[stable(feature = "sync_poison", since = "1.2.0")]
    568    pub fn is_poisoned(&self) -> bool {
    569        self.poison.get()
    570    }
    571
    572    /// Clear the poisoned state from a lock.
    573    ///
    574    /// If the lock is poisoned, it will remain poisoned until this function is called. This allows
    575    /// recovering from a poisoned state and marking that it has recovered. For example, if the
    576    /// value is overwritten by a known-good value, then the lock can be marked as un-poisoned. Or
    577    /// possibly, the value could be inspected to determine if it is in a consistent state, and if
    578    /// so the poison is removed.
    579    ///
    580    /// # Examples
    581    ///
    582    /// ```
    583    /// use std::sync::{Arc, RwLock};
    584    /// use std::thread;
    585    ///
    586    /// let lock = Arc::new(RwLock::new(0));
    587    /// let c_lock = Arc::clone(&lock);
    588    ///
    589    /// let _ = thread::spawn(move || {
    590    ///     let _lock = c_lock.write().unwrap();
    591    ///     panic!(); // the lock gets poisoned
    592    /// }).join();
    593    ///
    594    /// assert_eq!(lock.is_poisoned(), true);
    595    /// let guard = lock.write().unwrap_or_else(|mut e| {
    596    ///     **e.get_mut() = 1;
    597    ///     lock.clear_poison();
    598    ///     e.into_inner()
    599    /// });
    600    /// assert_eq!(lock.is_poisoned(), false);
    601    /// assert_eq!(*guard, 1);
    602    /// ```
    603    #[inline]
    604    #[stable(feature = "mutex_unpoison", since = "1.77.0")]
    605    pub fn clear_poison(&self) {
    606        self.poison.clear();
    607    }
    608
    609    /// Consumes this `RwLock`, returning the underlying data.
    610    ///
    611    /// # Errors
    612    ///
    613    /// This function will return an error containing the underlying data if
    614    /// the `RwLock` is poisoned. An `RwLock` is poisoned whenever a writer
    615    /// panics while holding an exclusive lock. An error will only be returned
    616    /// if the lock would have otherwise been acquired.
    617    ///
    618    /// # Examples
    619    ///
    620    /// ```
    621    /// use std::sync::RwLock;
    622    ///
    623    /// let lock = RwLock::new(String::new());
    624    /// {
    625    ///     let mut s = lock.write().unwrap();
    626    ///     *s = "modified".to_owned();
    627    /// }
    628    /// assert_eq!(lock.into_inner().unwrap(), "modified");
    629    /// ```
    630    #[stable(feature = "rwlock_into_inner", since = "1.6.0")]
    631    pub fn into_inner(self) -> LockResult<T>
    632    where
    633        T: Sized,
    634    {
    635        let data = self.data.into_inner();
    636        poison::map_result(self.poison.borrow(), |()| data)
    637    }
    638
    639    /// Returns a mutable reference to the underlying data.
    640    ///
    641    /// Since this call borrows the `RwLock` mutably, no actual locking needs to
    642    /// take place -- the mutable borrow statically guarantees no new locks can be acquired
    643    /// while this reference exists. Note that this method does not clear any previously abandoned
    644    /// locks (e.g., via [`forget()`] on a [`RwLockReadGuard`] or [`RwLockWriteGuard`]).
    645    ///
    646    /// # Errors
    647    ///
    648    /// This function will return an error containing a mutable reference to
    649    /// the underlying data if the `RwLock` is poisoned. An `RwLock` is
    650    /// poisoned whenever a writer panics while holding an exclusive lock.
    651    /// An error will only be returned if the lock would have otherwise been
    652    /// acquired.
    653    ///
    654    /// # Examples
    655    ///
    656    /// ```
    657    /// use std::sync::RwLock;
    658    ///
    659    /// let mut lock = RwLock::new(0);
    660    /// *lock.get_mut().unwrap() = 10;
    661    /// assert_eq!(*lock.read().unwrap(), 10);
    662    /// ```
    663    #[stable(feature = "rwlock_get_mut", since = "1.6.0")]
    664    pub fn get_mut(&mut self) -> LockResult<&mut T> {
    665        let data = self.data.get_mut();
    666        poison::map_result(self.poison.borrow(), |()| data)
    667    }
    668
    669    /// Returns a raw pointer to the underlying data.
    670    ///
    671    /// The returned pointer is always non-null and properly aligned, but it is
    672    /// the user's responsibility to ensure that any reads and writes through it
    673    /// are properly synchronized to avoid data races, and that it is not read
    674    /// or written through after the lock is dropped.
    675    #[unstable(feature = "rwlock_data_ptr", issue = "140368")]
    676    pub const fn data_ptr(&self) -> *mut T {
    677        self.data.get()
    678    }
    679}
    680
    681#[stable(feature = "rust1", since = "1.0.0")]
    682impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
    683    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    684        let mut d = f.debug_struct("RwLock");
    685        match self.try_read() {
    686            Ok(guard) => {
    687                d.field("data", &&*guard);
    688            }
    689            Err(TryLockError::Poisoned(err)) => {
    690                d.field("data", &&**err.get_ref());
    691            }
    692            Err(TryLockError::WouldBlock) => {
    693                d.field("data", &format_args!("<locked>"));
    694            }
    695        }
    696        d.field("poisoned", &self.poison.get());
    697        d.finish_non_exhaustive()
    698    }
    699}
    700
    701#[stable(feature = "rw_lock_default", since = "1.10.0")]
    702impl<T: Default> Default for RwLock<T> {
    703    /// Creates a new `RwLock<T>`, with the `Default` value for T.
    704    fn default() -> RwLock<T> {
    705        RwLock::new(Default::default())
    706    }
    707}
    708
    709#[stable(feature = "rw_lock_from", since = "1.24.0")]
    710impl<T> From<T> for RwLock<T> {
    711    /// Creates a new instance of an `RwLock<T>` which is unlocked.
    712    /// This is equivalent to [`RwLock::new`].
    713    fn from(t: T) -> Self {
    714        RwLock::new(t)
    715    }
    716}
    717
    718impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
    719    /// Creates a new instance of `RwLockReadGuard<T>` from a `RwLock<T>`.
    720    ///
    721    /// # Safety
    722    ///
    723    /// This function is safe if and only if the same thread has successfully and safely called
    724    /// `lock.inner.read()`, `lock.inner.try_read()`, or `lock.inner.downgrade()` before
    725    /// instantiating this object.
    726    unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockReadGuard<'rwlock, T>> {
    727        poison::map_result(lock.poison.borrow(), |()| RwLockReadGuard {
    728            data: unsafe { NonNull::new_unchecked(lock.data.get()) },
    729            inner_lock: &lock.inner,
    730        })
    731    }
    732
    733    /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data, e.g.
    734    /// an enum variant.
    735    ///
    736    /// The `RwLock` is already locked for reading, so this cannot fail.
    737    ///
    738    /// This is an associated function that needs to be used as
    739    /// `RwLockReadGuard::map(...)`. A method would interfere with methods of
    740    /// the same name on the contents of the `RwLockReadGuard` used through
    741    /// `Deref`.
    742    ///
    743    /// # Panics
    744    ///
    745    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be
    746    /// poisoned.
    747    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
    748    pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockReadGuard<'rwlock, U>
    749    where
    750        F: FnOnce(&T) -> &U,
    751        U: ?Sized,
    752    {
    753        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
    754        // was created, and have been upheld throughout `map` and/or `filter_map`.
    755        // The signature of the closure guarantees that it will not "leak" the lifetime of the
    756        // reference passed to it. If the closure panics, the guard will be dropped.
    757        let data = NonNull::from(f(unsafe { orig.data.as_ref() }));
    758        let orig = ManuallyDrop::new(orig);
    759        MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock }
    760    }
    761
    762    /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data. The
    763    /// original guard is returned as an `Err(...)` if the closure returns
    764    /// `None`.
    765    ///
    766    /// The `RwLock` is already locked for reading, so this cannot fail.
    767    ///
    768    /// This is an associated function that needs to be used as
    769    /// `RwLockReadGuard::filter_map(...)`. A method would interfere with methods
    770    /// of the same name on the contents of the `RwLockReadGuard` used through
    771    /// `Deref`.
    772    ///
    773    /// # Panics
    774    ///
    775    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be
    776    /// poisoned.
    777    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
    778    pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'rwlock, U>, Self>
    779    where
    780        F: FnOnce(&T) -> Option<&U>,
    781        U: ?Sized,
    782    {
    783        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
    784        // was created, and have been upheld throughout `map` and/or `filter_map`.
    785        // The signature of the closure guarantees that it will not "leak" the lifetime of the
    786        // reference passed to it. If the closure panics, the guard will be dropped.
    787        match f(unsafe { orig.data.as_ref() }) {
    788            Some(data) => {
    789                let data = NonNull::from(data);
    790                let orig = ManuallyDrop::new(orig);
    791                Ok(MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock })
    792            }
    793            None => Err(orig),
    794        }
    795    }
    796}
    797
    798impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
    799    /// Creates a new instance of `RwLockWriteGuard<T>` from a `RwLock<T>`.
    800    ///
    801    /// # Safety
    802    ///
    803    /// This function is safe if and only if the same thread has successfully and safely called
    804    /// `lock.inner.write()`, `lock.inner.try_write()`, or `lock.inner.try_upgrade` before
    805    /// instantiating this object.
    806    unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockWriteGuard<'rwlock, T>> {
    807        poison::map_result(lock.poison.guard(), |guard| RwLockWriteGuard { lock, poison: guard })
    808    }
    809
    810    /// Downgrades a write-locked `RwLockWriteGuard` into a read-locked [`RwLockReadGuard`].
    811    ///
    812    /// Since we have the `RwLockWriteGuard`, the [`RwLock`] must already be locked for writing, so
    813    /// this method cannot fail.
    814    ///
    815    /// After downgrading, other readers will be allowed to read the protected data.
    816    ///
    817    /// # Examples
    818    ///
    819    /// `downgrade` takes ownership of the `RwLockWriteGuard` and returns a [`RwLockReadGuard`].
    820    ///
    821    /// ```
    822    /// use std::sync::{RwLock, RwLockWriteGuard};
    823    ///
    824    /// let rw = RwLock::new(0);
    825    ///
    826    /// let mut write_guard = rw.write().unwrap();
    827    /// *write_guard = 42;
    828    ///
    829    /// let read_guard = RwLockWriteGuard::downgrade(write_guard);
    830    /// assert_eq!(42, *read_guard);
    831    /// ```
    832    ///
    833    /// `downgrade` will _atomically_ change the state of the [`RwLock`] from exclusive mode into
    834    /// shared mode. This means that it is impossible for another writing thread to get in between a
    835    /// thread calling `downgrade` and any reads it performs after downgrading.
    836    ///
    837    /// ```
    838    /// use std::sync::{Arc, RwLock, RwLockWriteGuard};
    839    ///
    840    /// let rw = Arc::new(RwLock::new(1));
    841    ///
    842    /// // Put the lock in write mode.
    843    /// let mut main_write_guard = rw.write().unwrap();
    844    ///
    845    /// let rw_clone = rw.clone();
    846    /// let evil_handle = std::thread::spawn(move || {
    847    ///     // This will not return until the main thread drops the `main_read_guard`.
    848    ///     let mut evil_guard = rw_clone.write().unwrap();
    849    ///
    850    ///     assert_eq!(*evil_guard, 2);
    851    ///     *evil_guard = 3;
    852    /// });
    853    ///
    854    /// *main_write_guard = 2;
    855    ///
    856    /// // Atomically downgrade the write guard into a read guard.
    857    /// let main_read_guard = RwLockWriteGuard::downgrade(main_write_guard);
    858    ///
    859    /// // Since `downgrade` is atomic, the writer thread cannot have changed the protected data.
    860    /// assert_eq!(*main_read_guard, 2, "`downgrade` was not atomic");
    861    /// #
    862    /// # drop(main_read_guard);
    863    /// # evil_handle.join().unwrap();
    864    /// #
    865    /// # let final_check = rw.read().unwrap();
    866    /// # assert_eq!(*final_check, 3);
    867    /// ```
    868    #[stable(feature = "rwlock_downgrade", since = "1.92.0")]
    869    pub fn downgrade(s: Self) -> RwLockReadGuard<'rwlock, T> {
    870        let lock = s.lock;
    871
    872        // We don't want to call the destructor since that calls `write_unlock`.
    873        forget(s);
    874
    875        // SAFETY: We take ownership of a write guard, so we must already have the `RwLock` in write
    876        // mode, satisfying the `downgrade` contract.
    877        unsafe { lock.inner.downgrade() };
    878
    879        // SAFETY: We have just successfully called `downgrade`, so we fulfill the safety contract.
    880        unsafe { RwLockReadGuard::new(lock).unwrap_or_else(PoisonError::into_inner) }
    881    }
    882
    883    /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data, e.g.
    884    /// an enum variant.
    885    ///
    886    /// The `RwLock` is already locked for writing, so this cannot fail.
    887    ///
    888    /// This is an associated function that needs to be used as
    889    /// `RwLockWriteGuard::map(...)`. A method would interfere with methods of
    890    /// the same name on the contents of the `RwLockWriteGuard` used through
    891    /// `Deref`.
    892    ///
    893    /// # Panics
    894    ///
    895    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
    896    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
    897    pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockWriteGuard<'rwlock, U>
    898    where
    899        F: FnOnce(&mut T) -> &mut U,
    900        U: ?Sized,
    901    {
    902        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
    903        // was created, and have been upheld throughout `map` and/or `filter_map`.
    904        // The signature of the closure guarantees that it will not "leak" the lifetime of the
    905        // reference passed to it. If the closure panics, the guard will be dropped.
    906        let data = NonNull::from(f(unsafe { &mut *orig.lock.data.get() }));
    907        let orig = ManuallyDrop::new(orig);
    908        MappedRwLockWriteGuard {
    909            data,
    910            inner_lock: &orig.lock.inner,
    911            poison_flag: &orig.lock.poison,
    912            poison_guard: orig.poison.clone(),
    913            _variance: PhantomData,
    914        }
    915    }
    916
    917    /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data. The
    918    /// original guard is returned as an `Err(...)` if the closure returns
    919    /// `None`.
    920    ///
    921    /// The `RwLock` is already locked for writing, so this cannot fail.
    922    ///
    923    /// This is an associated function that needs to be used as
    924    /// `RwLockWriteGuard::filter_map(...)`. A method would interfere with methods
    925    /// of the same name on the contents of the `RwLockWriteGuard` used through
    926    /// `Deref`.
    927    ///
    928    /// # Panics
    929    ///
    930    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
    931    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
    932    pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'rwlock, U>, Self>
    933    where
    934        F: FnOnce(&mut T) -> Option<&mut U>,
    935        U: ?Sized,
    936    {
    937        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
    938        // was created, and have been upheld throughout `map` and/or `filter_map`.
    939        // The signature of the closure guarantees that it will not "leak" the lifetime of the
    940        // reference passed to it. If the closure panics, the guard will be dropped.
    941        match f(unsafe { &mut *orig.lock.data.get() }) {
    942            Some(data) => {
    943                let data = NonNull::from(data);
    944                let orig = ManuallyDrop::new(orig);
    945                Ok(MappedRwLockWriteGuard {
    946                    data,
    947                    inner_lock: &orig.lock.inner,
    948                    poison_flag: &orig.lock.poison,
    949                    poison_guard: orig.poison.clone(),
    950                    _variance: PhantomData,
    951                })
    952            }
    953            None => Err(orig),
    954        }
    955    }
    956}
    957
    958impl<'rwlock, T: ?Sized> MappedRwLockReadGuard<'rwlock, T> {
    959    /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data,
    960    /// e.g. an enum variant.
    961    ///
    962    /// The `RwLock` is already locked for reading, so this cannot fail.
    963    ///
    964    /// This is an associated function that needs to be used as
    965    /// `MappedRwLockReadGuard::map(...)`. A method would interfere with
    966    /// methods of the same name on the contents of the `MappedRwLockReadGuard`
    967    /// used through `Deref`.
    968    ///
    969    /// # Panics
    970    ///
    971    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be
    972    /// poisoned.
    973    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
    974    pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockReadGuard<'rwlock, U>
    975    where
    976        F: FnOnce(&T) -> &U,
    977        U: ?Sized,
    978    {
    979        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
    980        // was created, and have been upheld throughout `map` and/or `filter_map`.
    981        // The signature of the closure guarantees that it will not "leak" the lifetime of the
    982        // reference passed to it. If the closure panics, the guard will be dropped.
    983        let data = NonNull::from(f(unsafe { orig.data.as_ref() }));
    984        let orig = ManuallyDrop::new(orig);
    985        MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock }
    986    }
    987
    988    /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data.
    989    /// The original guard is returned as an `Err(...)` if the closure returns
    990    /// `None`.
    991    ///
    992    /// The `RwLock` is already locked for reading, so this cannot fail.
    993    ///
    994    /// This is an associated function that needs to be used as
    995    /// `MappedRwLockReadGuard::filter_map(...)`. A method would interfere with
    996    /// methods of the same name on the contents of the `MappedRwLockReadGuard`
    997    /// used through `Deref`.
    998    ///
    999    /// # Panics
    1000    ///
    1001    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be
    1002    /// poisoned.
    1003    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
    1004    pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'rwlock, U>, Self>
    1005    where
    1006        F: FnOnce(&T) -> Option<&U>,
    1007        U: ?Sized,
    1008    {
    1009        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
    1010        // was created, and have been upheld throughout `map` and/or `filter_map`.
    1011        // The signature of the closure guarantees that it will not "leak" the lifetime of the
    1012        // reference passed to it. If the closure panics, the guard will be dropped.
    1013        match f(unsafe { orig.data.as_ref() }) {
    1014            Some(data) => {
    1015                let data = NonNull::from(data);
    1016                let orig = ManuallyDrop::new(orig);
    1017                Ok(MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock })
    1018            }
    1019            None => Err(orig),
    1020        }
    1021    }
    1022}
    1023
    1024impl<'rwlock, T: ?Sized> MappedRwLockWriteGuard<'rwlock, T> {
    1025    /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data,
    1026    /// e.g. an enum variant.
    1027    ///
    1028    /// The `RwLock` is already locked for writing, so this cannot fail.
    1029    ///
    1030    /// This is an associated function that needs to be used as
    1031    /// `MappedRwLockWriteGuard::map(...)`. A method would interfere with
    1032    /// methods of the same name on the contents of the `MappedRwLockWriteGuard`
    1033    /// used through `Deref`.
    1034    ///
    1035    /// # Panics
    1036    ///
    1037    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
    1038    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
    1039    pub fn map<U, F>(mut orig: Self, f: F) -> MappedRwLockWriteGuard<'rwlock, U>
    1040    where
    1041        F: FnOnce(&mut T) -> &mut U,
    1042        U: ?Sized,
    1043    {
    1044        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
    1045        // was created, and have been upheld throughout `map` and/or `filter_map`.
    1046        // The signature of the closure guarantees that it will not "leak" the lifetime of the
    1047        // reference passed to it. If the closure panics, the guard will be dropped.
    1048        let data = NonNull::from(f(unsafe { orig.data.as_mut() }));
    1049        let orig = ManuallyDrop::new(orig);
    1050        MappedRwLockWriteGuard {
    1051            data,
    1052            inner_lock: orig.inner_lock,
    1053            poison_flag: orig.poison_flag,
    1054            poison_guard: orig.poison_guard.clone(),
    1055            _variance: PhantomData,
    1056        }
    1057    }
    1058
    1059    /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data.
    1060    /// The original guard is returned as an `Err(...)` if the closure returns
    1061    /// `None`.
    1062    ///
    1063    /// The `RwLock` is already locked for writing, so this cannot fail.
    1064    ///
    1065    /// This is an associated function that needs to be used as
    1066    /// `MappedRwLockWriteGuard::filter_map(...)`. A method would interfere with
    1067    /// methods of the same name on the contents of the `MappedRwLockWriteGuard`
    1068    /// used through `Deref`.
    1069    ///
    1070    /// # Panics
    1071    ///
    1072    /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
    1073    #[unstable(feature = "mapped_lock_guards", issue = "117108")]
    1074    pub fn filter_map<U, F>(
    1075        mut orig: Self,
    1076        f: F,
    1077    ) -> Result<MappedRwLockWriteGuard<'rwlock, U>, Self>
    1078    where
    1079        F: FnOnce(&mut T) -> Option<&mut U>,
    1080        U: ?Sized,
    1081    {
    1082        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
    1083        // was created, and have been upheld throughout `map` and/or `filter_map`.
    1084        // The signature of the closure guarantees that it will not "leak" the lifetime of the
    1085        // reference passed to it. If the closure panics, the guard will be dropped.
    1086        match f(unsafe { orig.data.as_mut() }) {
    1087            Some(data) => {
    1088                let data = NonNull::from(data);
    1089                let orig = ManuallyDrop::new(orig);
    1090                Ok(MappedRwLockWriteGuard {
    1091                    data,
    1092                    inner_lock: orig.inner_lock,
    1093                    poison_flag: orig.poison_flag,
    1094                    poison_guard: orig.poison_guard.clone(),
    1095                    _variance: PhantomData,
    1096                })
    1097            }
    1098            None => Err(orig),
    1099        }
    1100    }
    1101}
    1102
    1103#[stable(feature = "rust1", since = "1.0.0")]
    1104impl<T: ?Sized> Drop for RwLockReadGuard<'_, T> {
    1105    fn drop(&mut self) {
    1106        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when created.
    1107        unsafe {
    1108            self.inner_lock.read_unlock();
    1109        }
    1110    }
    1111}
    1112
    1113#[stable(feature = "rust1", since = "1.0.0")]
    1114impl<T: ?Sized> Drop for RwLockWriteGuard<'_, T> {
    1115    fn drop(&mut self) {
    1116        self.lock.poison.done(&self.poison);
    1117        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when created.
    1118        unsafe {
    1119            self.lock.inner.write_unlock();
    1120        }
    1121    }
    1122}
    1123
    1124#[unstable(feature = "mapped_lock_guards", issue = "117108")]
    1125impl<T: ?Sized> Drop for MappedRwLockReadGuard<'_, T> {
    1126    fn drop(&mut self) {
    1127        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
    1128        // was created, and have been upheld throughout `map` and/or `filter_map`.
    1129        unsafe {
    1130            self.inner_lock.read_unlock();
    1131        }
    1132    }
    1133}
    1134
    1135#[unstable(feature = "mapped_lock_guards", issue = "117108")]
    1136impl<T: ?Sized> Drop for MappedRwLockWriteGuard<'_, T> {
    1137    fn drop(&mut self) {
    1138        self.poison_flag.done(&self.poison_guard);
    1139        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
    1140        // was created, and have been upheld throughout `map` and/or `filter_map`.
    1141        unsafe {
    1142            self.inner_lock.write_unlock();
    1143        }
    1144    }
    1145}
    1146
    1147#[stable(feature = "rust1", since = "1.0.0")]
    1148impl<T: ?Sized> Deref for RwLockReadGuard<'_, T> {
    1149    type Target = T;
    1150
    1151    fn deref(&self) -> &T {
    1152        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when created.
    1153        unsafe { self.data.as_ref() }
    1154    }
    1155}
    1156
    1157#[stable(feature = "rust1", since = "1.0.0")]
    1158impl<T: ?Sized> Deref for RwLockWriteGuard<'_, T> {
    1159    type Target = T;
    1160
    1161    fn deref(&self) -> &T {
    1162        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when created.
    1163        unsafe { &*self.lock.data.get() }
    1164    }
    1165}
    1166
    1167#[stable(feature = "rust1", since = "1.0.0")]
    1168impl<T: ?Sized> DerefMut for RwLockWriteGuard<'_, T> {
    1169    fn deref_mut(&mut self) -> &mut T {
    1170        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when created.
    1171        unsafe { &mut *self.lock.data.get() }
    1172    }
    1173}
    1174
    1175#[unstable(feature = "mapped_lock_guards", issue = "117108")]
    1176impl<T: ?Sized> Deref for MappedRwLockReadGuard<'_, T> {
    1177    type Target = T;
    1178
    1179    fn deref(&self) -> &T {
    1180        // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
    1181        // was created, and have been upheld throughout `map` and/or `filter_map`.
    1182        unsafe { self.data.as_ref() }
    1183    }
    1184}
    1185
    1186#[unstable(feature = "mapped_lock_guards", issue = "117108")]
    1187impl<T: ?Sized> Deref for MappedRwLockWriteGuard<'_, T> {
    1188    type Target = T;
    1189
    1190    fn deref(&self) -> &T {
    1191        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
    1192        // was created, and have been upheld throughout `map` and/or `filter_map`.
    1193        unsafe { self.data.as_ref() }
    1194    }
    1195}
    1196
    1197#[unstable(feature = "mapped_lock_guards", issue = "117108")]
    1198impl<T: ?Sized> DerefMut for MappedRwLockWriteGuard<'_, T> {
    1199    fn deref_mut(&mut self) -> &mut T {
    1200        // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
    1201        // was created, and have been upheld throughout `map` and/or `filter_map`.
    1202        unsafe { self.data.as_mut() }
    1203    }
    1204}
    1205
    1206#[stable(feature = "std_debug", since = "1.16.0")]
    1207impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLockReadGuard<'_, T> {
    1208    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    1209        (**self).fmt(f)
    1210    }
    1211}
    1212
    1213#[stable(feature = "std_guard_impls", since = "1.20.0")]
    1214impl<T: ?Sized + fmt::Display> fmt::Display for RwLockReadGuard<'_, T> {
    1215    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    1216        (**self).fmt(f)
    1217    }
    1218}
    1219
    1220#[stable(feature = "std_debug", since = "1.16.0")]
    1221impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLockWriteGuard<'_, T> {
    1222    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    1223        (**self).fmt(f)
    1224    }
    1225}
    1226
    1227#[stable(feature = "std_guard_impls", since = "1.20.0")]
    1228impl<T: ?Sized + fmt::Display> fmt::Display for RwLockWriteGuard<'_, T> {
    1229    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    1230        (**self).fmt(f)
    1231    }
    1232}
    1233
    1234#[unstable(feature = "mapped_lock_guards", issue = "117108")]
    1235impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedRwLockReadGuard<'_, T> {
    1236    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    1237        (**self).fmt(f)
    1238    }
    1239}
    1240
    1241#[unstable(feature = "mapped_lock_guards", issue = "117108")]
    1242impl<T: ?Sized + fmt::Display> fmt::Display for MappedRwLockReadGuard<'_, T> {
    1243    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    1244        (**self).fmt(f)
    1245    }
    1246}
    1247
    1248#[unstable(feature = "mapped_lock_guards", issue = "117108")]
    1249impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedRwLockWriteGuard<'_, T> {
    1250    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    1251        (**self).fmt(f)
    1252    }
    1253}
    1254
    1255#[unstable(feature = "mapped_lock_guards", issue = "117108")]
    1256impl<T: ?Sized + fmt::Display> fmt::Display for MappedRwLockWriteGuard<'_, T> {
    1257    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    1258        (**self).fmt(f)
    1259    }
    1260}