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}