Skip to main content

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