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 pub fn set(&self, value: T) -> Result<(), PoisonError<T>> {
303 if mem::needs_drop::<T>() {
304 // If the contained value has non-trivial destructor, we
305 // call that destructor after the lock being released.
306 self.replace(value).map(drop)
307 } else {
308 match self.write() {
309 Ok(mut guard) => {
310 *guard = value;
311
312 Ok(())
313 }
314 Err(_) => Err(PoisonError::new(value)),
315 }
316 }
317 }
318
319 /// Replaces the contained value with `value`, and returns the old contained value.
320 ///
321 /// # Errors
322 ///
323 /// This function will return an error containing the provided `value` if
324 /// the `RwLock` is poisoned. An `RwLock` is poisoned whenever a writer
325 /// panics while holding an exclusive lock.
326 ///
327 /// # Examples
328 ///
329 /// ```
330 /// #![feature(lock_value_accessors)]
331 ///
332 /// use std::sync::RwLock;
333 ///
334 /// let mut lock = RwLock::new(7);
335 ///
336 /// assert_eq!(lock.replace(11).unwrap(), 7);
337 /// assert_eq!(lock.get_cloned().unwrap(), 11);
338 /// ```
339 #[unstable(feature = "lock_value_accessors", issue = "133407")]
340 pub fn replace(&self, value: T) -> LockResult<T> {
341 match self.write() {
342 Ok(mut guard) => Ok(mem::replace(&mut *guard, value)),
343 Err(_) => Err(PoisonError::new(value)),
344 }
345 }
346}
347
348impl<T: ?Sized> RwLock<T> {
349 /// Locks this `RwLock` with shared read access, blocking the current thread
350 /// until it can be acquired.
351 ///
352 /// The calling thread will be blocked until there are no more writers which
353 /// hold the lock. There may be other readers currently inside the lock when
354 /// this method returns. This method does not provide any guarantees with
355 /// respect to the ordering of whether contentious readers or writers will
356 /// acquire the lock first.
357 ///
358 /// Returns an RAII guard which will release this thread's shared access
359 /// once it is dropped.
360 ///
361 /// # Errors
362 ///
363 /// This function will return an error if the `RwLock` is poisoned. An
364 /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
365 /// lock. The failure will occur immediately after the lock has been
366 /// acquired. The acquired lock guard will be contained in the returned
367 /// error.
368 ///
369 /// # Panics
370 ///
371 /// This function might panic when called if the lock is already held by the current thread.
372 ///
373 /// # Examples
374 ///
375 /// ```
376 /// use std::sync::{Arc, RwLock};
377 /// use std::thread;
378 ///
379 /// let lock = Arc::new(RwLock::new(1));
380 /// let c_lock = Arc::clone(&lock);
381 ///
382 /// let n = lock.read().unwrap();
383 /// assert_eq!(*n, 1);
384 ///
385 /// thread::spawn(move || {
386 /// let r = c_lock.read();
387 /// assert!(r.is_ok());
388 /// }).join().unwrap();
389 /// ```
390 #[inline]
391 #[stable(feature = "rust1", since = "1.0.0")]
392 pub fn read(&self) -> LockResult<RwLockReadGuard<'_, T>> {
393 unsafe {
394 self.inner.read();
395 RwLockReadGuard::new(self)
396 }
397 }
398
399 /// Attempts to acquire this `RwLock` with shared read access.
400 ///
401 /// If the access could not be granted at this time, then `Err` is returned.
402 /// Otherwise, an RAII guard is returned which will release the shared access
403 /// when it is dropped.
404 ///
405 /// This function does not block.
406 ///
407 /// This function does not provide any guarantees with respect to the ordering
408 /// of whether contentious readers or writers will acquire the lock first.
409 ///
410 /// # Errors
411 ///
412 /// This function will return the [`Poisoned`] error if the `RwLock` is
413 /// poisoned. An `RwLock` is poisoned whenever a writer panics while holding
414 /// an exclusive lock. `Poisoned` will only be returned if the lock would
415 /// have otherwise been acquired. An acquired lock guard will be contained
416 /// in the returned error.
417 ///
418 /// This function will return the [`WouldBlock`] error if the `RwLock` could
419 /// not be acquired because it was already locked exclusively.
420 ///
421 /// [`Poisoned`]: TryLockError::Poisoned
422 /// [`WouldBlock`]: TryLockError::WouldBlock
423 ///
424 /// # Examples
425 ///
426 /// ```
427 /// use std::sync::RwLock;
428 ///
429 /// let lock = RwLock::new(1);
430 ///
431 /// match lock.try_read() {
432 /// Ok(n) => assert_eq!(*n, 1),
433 /// Err(_) => unreachable!(),
434 /// };
435 /// ```
436 #[inline]
437 #[stable(feature = "rust1", since = "1.0.0")]
438 pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<'_, T>> {
439 unsafe {
440 if self.inner.try_read() {
441 Ok(RwLockReadGuard::new(self)?)
442 } else {
443 Err(TryLockError::WouldBlock)
444 }
445 }
446 }
447
448 /// Locks this `RwLock` with exclusive write access, blocking the current
449 /// thread until it can be acquired.
450 ///
451 /// This function will not return while other writers or other readers
452 /// currently have access to the lock.
453 ///
454 /// Returns an RAII guard which will drop the write access of this `RwLock`
455 /// when dropped.
456 ///
457 /// # Errors
458 ///
459 /// This function will return an error if the `RwLock` is poisoned. An
460 /// `RwLock` is poisoned whenever a writer panics while holding an exclusive
461 /// lock. An error will be returned when the lock is acquired. The acquired
462 /// lock guard will be contained in the returned error.
463 ///
464 /// # Panics
465 ///
466 /// This function might panic when called if the lock is already held by the current thread.
467 ///
468 /// # Examples
469 ///
470 /// ```
471 /// use std::sync::RwLock;
472 ///
473 /// let lock = RwLock::new(1);
474 ///
475 /// let mut n = lock.write().unwrap();
476 /// *n = 2;
477 ///
478 /// assert!(lock.try_read().is_err());
479 /// ```
480 #[inline]
481 #[stable(feature = "rust1", since = "1.0.0")]
482 pub fn write(&self) -> LockResult<RwLockWriteGuard<'_, T>> {
483 unsafe {
484 self.inner.write();
485 RwLockWriteGuard::new(self)
486 }
487 }
488
489 /// Attempts to lock this `RwLock` with exclusive write access.
490 ///
491 /// If the lock could not be acquired at this time, then `Err` is returned.
492 /// Otherwise, an RAII guard is returned which will release the lock when
493 /// it is dropped.
494 ///
495 /// This function does not block.
496 ///
497 /// This function does not provide any guarantees with respect to the ordering
498 /// of whether contentious readers or writers will acquire the lock first.
499 ///
500 /// # Errors
501 ///
502 /// This function will return the [`Poisoned`] error if the `RwLock` is
503 /// poisoned. An `RwLock` is poisoned whenever a writer panics while holding
504 /// an exclusive lock. `Poisoned` will only be returned if the lock would
505 /// have otherwise been acquired. An acquired lock guard will be contained
506 /// in the returned error.
507 ///
508 /// This function will return the [`WouldBlock`] error if the `RwLock` could
509 /// not be acquired because it was already locked.
510 ///
511 /// [`Poisoned`]: TryLockError::Poisoned
512 /// [`WouldBlock`]: TryLockError::WouldBlock
513 ///
514 ///
515 /// # Examples
516 ///
517 /// ```
518 /// use std::sync::RwLock;
519 ///
520 /// let lock = RwLock::new(1);
521 ///
522 /// let n = lock.read().unwrap();
523 /// assert_eq!(*n, 1);
524 ///
525 /// assert!(lock.try_write().is_err());
526 /// ```
527 #[inline]
528 #[stable(feature = "rust1", since = "1.0.0")]
529 pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<'_, T>> {
530 unsafe {
531 if self.inner.try_write() {
532 Ok(RwLockWriteGuard::new(self)?)
533 } else {
534 Err(TryLockError::WouldBlock)
535 }
536 }
537 }
538
539 /// Determines whether the lock is poisoned.
540 ///
541 /// If another thread is active, the lock can still become poisoned at any
542 /// time. You should not trust a `false` value for program correctness
543 /// without additional synchronization.
544 ///
545 /// # Examples
546 ///
547 /// ```
548 /// use std::sync::{Arc, RwLock};
549 /// use std::thread;
550 ///
551 /// let lock = Arc::new(RwLock::new(0));
552 /// let c_lock = Arc::clone(&lock);
553 ///
554 /// let _ = thread::spawn(move || {
555 /// let _lock = c_lock.write().unwrap();
556 /// panic!(); // the lock gets poisoned
557 /// }).join();
558 /// assert_eq!(lock.is_poisoned(), true);
559 /// ```
560 #[inline]
561 #[stable(feature = "sync_poison", since = "1.2.0")]
562 pub fn is_poisoned(&self) -> bool {
563 self.poison.get()
564 }
565
566 /// Clear the poisoned state from a lock.
567 ///
568 /// If the lock is poisoned, it will remain poisoned until this function is called. This allows
569 /// recovering from a poisoned state and marking that it has recovered. For example, if the
570 /// value is overwritten by a known-good value, then the lock can be marked as un-poisoned. Or
571 /// possibly, the value could be inspected to determine if it is in a consistent state, and if
572 /// so the poison is removed.
573 ///
574 /// # Examples
575 ///
576 /// ```
577 /// use std::sync::{Arc, RwLock};
578 /// use std::thread;
579 ///
580 /// let lock = Arc::new(RwLock::new(0));
581 /// let c_lock = Arc::clone(&lock);
582 ///
583 /// let _ = thread::spawn(move || {
584 /// let _lock = c_lock.write().unwrap();
585 /// panic!(); // the lock gets poisoned
586 /// }).join();
587 ///
588 /// assert_eq!(lock.is_poisoned(), true);
589 /// let guard = lock.write().unwrap_or_else(|mut e| {
590 /// **e.get_mut() = 1;
591 /// lock.clear_poison();
592 /// e.into_inner()
593 /// });
594 /// assert_eq!(lock.is_poisoned(), false);
595 /// assert_eq!(*guard, 1);
596 /// ```
597 #[inline]
598 #[stable(feature = "mutex_unpoison", since = "1.77.0")]
599 pub fn clear_poison(&self) {
600 self.poison.clear();
601 }
602
603 /// Consumes this `RwLock`, returning the underlying data.
604 ///
605 /// # Errors
606 ///
607 /// This function will return an error containing the underlying data if
608 /// the `RwLock` is poisoned. An `RwLock` is poisoned whenever a writer
609 /// panics while holding an exclusive lock. An error will only be returned
610 /// if the lock would have otherwise been acquired.
611 ///
612 /// # Examples
613 ///
614 /// ```
615 /// use std::sync::RwLock;
616 ///
617 /// let lock = RwLock::new(String::new());
618 /// {
619 /// let mut s = lock.write().unwrap();
620 /// *s = "modified".to_owned();
621 /// }
622 /// assert_eq!(lock.into_inner().unwrap(), "modified");
623 /// ```
624 #[stable(feature = "rwlock_into_inner", since = "1.6.0")]
625 pub fn into_inner(self) -> LockResult<T>
626 where
627 T: Sized,
628 {
629 let data = self.data.into_inner();
630 poison::map_result(self.poison.borrow(), |()| data)
631 }
632
633 /// Returns a mutable reference to the underlying data.
634 ///
635 /// Since this call borrows the `RwLock` mutably, no actual locking needs to
636 /// take place -- the mutable borrow statically guarantees no new locks can be acquired
637 /// while this reference exists. Note that this method does not clear any previously abandoned
638 /// locks (e.g., via [`forget()`] on a [`RwLockReadGuard`] or [`RwLockWriteGuard`]).
639 ///
640 /// # Errors
641 ///
642 /// This function will return an error containing a mutable reference to
643 /// the underlying data if the `RwLock` is poisoned. An `RwLock` is
644 /// poisoned whenever a writer panics while holding an exclusive lock.
645 /// An error will only be returned if the lock would have otherwise been
646 /// acquired.
647 ///
648 /// # Examples
649 ///
650 /// ```
651 /// use std::sync::RwLock;
652 ///
653 /// let mut lock = RwLock::new(0);
654 /// *lock.get_mut().unwrap() = 10;
655 /// assert_eq!(*lock.read().unwrap(), 10);
656 /// ```
657 #[stable(feature = "rwlock_get_mut", since = "1.6.0")]
658 pub fn get_mut(&mut self) -> LockResult<&mut T> {
659 let data = self.data.get_mut();
660 poison::map_result(self.poison.borrow(), |()| data)
661 }
662
663 /// Returns a raw pointer to the underlying data.
664 ///
665 /// The returned pointer is always non-null and properly aligned, but it is
666 /// the user's responsibility to ensure that any reads and writes through it
667 /// are properly synchronized to avoid data races, and that it is not read
668 /// or written through after the lock is dropped.
669 #[unstable(feature = "rwlock_data_ptr", issue = "140368")]
670 pub fn data_ptr(&self) -> *mut T {
671 self.data.get()
672 }
673}
674
675#[stable(feature = "rust1", since = "1.0.0")]
676impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
677 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
678 let mut d = f.debug_struct("RwLock");
679 match self.try_read() {
680 Ok(guard) => {
681 d.field("data", &&*guard);
682 }
683 Err(TryLockError::Poisoned(err)) => {
684 d.field("data", &&**err.get_ref());
685 }
686 Err(TryLockError::WouldBlock) => {
687 d.field("data", &format_args!("<locked>"));
688 }
689 }
690 d.field("poisoned", &self.poison.get());
691 d.finish_non_exhaustive()
692 }
693}
694
695#[stable(feature = "rw_lock_default", since = "1.10.0")]
696impl<T: Default> Default for RwLock<T> {
697 /// Creates a new `RwLock<T>`, with the `Default` value for T.
698 fn default() -> RwLock<T> {
699 RwLock::new(Default::default())
700 }
701}
702
703#[stable(feature = "rw_lock_from", since = "1.24.0")]
704impl<T> From<T> for RwLock<T> {
705 /// Creates a new instance of an `RwLock<T>` which is unlocked.
706 /// This is equivalent to [`RwLock::new`].
707 fn from(t: T) -> Self {
708 RwLock::new(t)
709 }
710}
711
712impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
713 /// Creates a new instance of `RwLockReadGuard<T>` from a `RwLock<T>`.
714 ///
715 /// # Safety
716 ///
717 /// This function is safe if and only if the same thread has successfully and safely called
718 /// `lock.inner.read()`, `lock.inner.try_read()`, or `lock.inner.downgrade()` before
719 /// instantiating this object.
720 unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockReadGuard<'rwlock, T>> {
721 poison::map_result(lock.poison.borrow(), |()| RwLockReadGuard {
722 data: unsafe { NonNull::new_unchecked(lock.data.get()) },
723 inner_lock: &lock.inner,
724 })
725 }
726
727 /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data, e.g.
728 /// an enum variant.
729 ///
730 /// The `RwLock` is already locked for reading, so this cannot fail.
731 ///
732 /// This is an associated function that needs to be used as
733 /// `RwLockReadGuard::map(...)`. A method would interfere with methods of
734 /// the same name on the contents of the `RwLockReadGuard` used through
735 /// `Deref`.
736 ///
737 /// # Panics
738 ///
739 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be
740 /// poisoned.
741 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
742 pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockReadGuard<'rwlock, U>
743 where
744 F: FnOnce(&T) -> &U,
745 U: ?Sized,
746 {
747 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
748 // was created, and have been upheld throughout `map` and/or `filter_map`.
749 // The signature of the closure guarantees that it will not "leak" the lifetime of the
750 // reference passed to it. If the closure panics, the guard will be dropped.
751 let data = NonNull::from(f(unsafe { orig.data.as_ref() }));
752 let orig = ManuallyDrop::new(orig);
753 MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock }
754 }
755
756 /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data. The
757 /// original guard is returned as an `Err(...)` if the closure returns
758 /// `None`.
759 ///
760 /// The `RwLock` is already locked for reading, so this cannot fail.
761 ///
762 /// This is an associated function that needs to be used as
763 /// `RwLockReadGuard::filter_map(...)`. A method would interfere with methods
764 /// of the same name on the contents of the `RwLockReadGuard` used through
765 /// `Deref`.
766 ///
767 /// # Panics
768 ///
769 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be
770 /// poisoned.
771 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
772 pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'rwlock, U>, Self>
773 where
774 F: FnOnce(&T) -> Option<&U>,
775 U: ?Sized,
776 {
777 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
778 // was created, and have been upheld throughout `map` and/or `filter_map`.
779 // The signature of the closure guarantees that it will not "leak" the lifetime of the
780 // reference passed to it. If the closure panics, the guard will be dropped.
781 match f(unsafe { orig.data.as_ref() }) {
782 Some(data) => {
783 let data = NonNull::from(data);
784 let orig = ManuallyDrop::new(orig);
785 Ok(MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock })
786 }
787 None => Err(orig),
788 }
789 }
790}
791
792impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
793 /// Creates a new instance of `RwLockWriteGuard<T>` from a `RwLock<T>`.
794 ///
795 /// # Safety
796 ///
797 /// This function is safe if and only if the same thread has successfully and safely called
798 /// `lock.inner.write()`, `lock.inner.try_write()`, or `lock.inner.try_upgrade` before
799 /// instantiating this object.
800 unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockWriteGuard<'rwlock, T>> {
801 poison::map_result(lock.poison.guard(), |guard| RwLockWriteGuard { lock, poison: guard })
802 }
803
804 /// Downgrades a write-locked `RwLockWriteGuard` into a read-locked [`RwLockReadGuard`].
805 ///
806 /// Since we have the `RwLockWriteGuard`, the [`RwLock`] must already be locked for writing, so
807 /// this method cannot fail.
808 ///
809 /// After downgrading, other readers will be allowed to read the protected data.
810 ///
811 /// # Examples
812 ///
813 /// `downgrade` takes ownership of the `RwLockWriteGuard` and returns a [`RwLockReadGuard`].
814 ///
815 /// ```
816 /// #![feature(rwlock_downgrade)]
817 ///
818 /// use std::sync::{RwLock, RwLockWriteGuard};
819 ///
820 /// let rw = RwLock::new(0);
821 ///
822 /// let mut write_guard = rw.write().unwrap();
823 /// *write_guard = 42;
824 ///
825 /// let read_guard = RwLockWriteGuard::downgrade(write_guard);
826 /// assert_eq!(42, *read_guard);
827 /// ```
828 ///
829 /// `downgrade` will _atomically_ change the state of the [`RwLock`] from exclusive mode into
830 /// shared mode. This means that it is impossible for another writing thread to get in between a
831 /// thread calling `downgrade` and any reads it performs after downgrading.
832 ///
833 /// ```
834 /// #![feature(rwlock_downgrade)]
835 ///
836 /// use std::sync::{Arc, RwLock, RwLockWriteGuard};
837 ///
838 /// let rw = Arc::new(RwLock::new(1));
839 ///
840 /// // Put the lock in write mode.
841 /// let mut main_write_guard = rw.write().unwrap();
842 ///
843 /// let rw_clone = rw.clone();
844 /// let evil_handle = std::thread::spawn(move || {
845 /// // This will not return until the main thread drops the `main_read_guard`.
846 /// let mut evil_guard = rw_clone.write().unwrap();
847 ///
848 /// assert_eq!(*evil_guard, 2);
849 /// *evil_guard = 3;
850 /// });
851 ///
852 /// *main_write_guard = 2;
853 ///
854 /// // Atomically downgrade the write guard into a read guard.
855 /// let main_read_guard = RwLockWriteGuard::downgrade(main_write_guard);
856 ///
857 /// // Since `downgrade` is atomic, the writer thread cannot have changed the protected data.
858 /// assert_eq!(*main_read_guard, 2, "`downgrade` was not atomic");
859 /// #
860 /// # drop(main_read_guard);
861 /// # evil_handle.join().unwrap();
862 /// #
863 /// # let final_check = rw.read().unwrap();
864 /// # assert_eq!(*final_check, 3);
865 /// ```
866 #[unstable(feature = "rwlock_downgrade", issue = "128203")]
867 pub fn downgrade(s: Self) -> RwLockReadGuard<'rwlock, T> {
868 let lock = s.lock;
869
870 // We don't want to call the destructor since that calls `write_unlock`.
871 forget(s);
872
873 // SAFETY: We take ownership of a write guard, so we must already have the `RwLock` in write
874 // mode, satisfying the `downgrade` contract.
875 unsafe { lock.inner.downgrade() };
876
877 // SAFETY: We have just successfully called `downgrade`, so we fulfill the safety contract.
878 unsafe { RwLockReadGuard::new(lock).unwrap_or_else(PoisonError::into_inner) }
879 }
880
881 /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data, e.g.
882 /// an enum variant.
883 ///
884 /// The `RwLock` is already locked for writing, so this cannot fail.
885 ///
886 /// This is an associated function that needs to be used as
887 /// `RwLockWriteGuard::map(...)`. A method would interfere with methods of
888 /// the same name on the contents of the `RwLockWriteGuard` used through
889 /// `Deref`.
890 ///
891 /// # Panics
892 ///
893 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
894 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
895 pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockWriteGuard<'rwlock, U>
896 where
897 F: FnOnce(&mut T) -> &mut U,
898 U: ?Sized,
899 {
900 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
901 // was created, and have been upheld throughout `map` and/or `filter_map`.
902 // The signature of the closure guarantees that it will not "leak" the lifetime of the
903 // reference passed to it. If the closure panics, the guard will be dropped.
904 let data = NonNull::from(f(unsafe { &mut *orig.lock.data.get() }));
905 let orig = ManuallyDrop::new(orig);
906 MappedRwLockWriteGuard {
907 data,
908 inner_lock: &orig.lock.inner,
909 poison_flag: &orig.lock.poison,
910 poison_guard: orig.poison.clone(),
911 _variance: PhantomData,
912 }
913 }
914
915 /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data. The
916 /// original guard is returned as an `Err(...)` if the closure returns
917 /// `None`.
918 ///
919 /// The `RwLock` is already locked for writing, so this cannot fail.
920 ///
921 /// This is an associated function that needs to be used as
922 /// `RwLockWriteGuard::filter_map(...)`. A method would interfere with methods
923 /// of the same name on the contents of the `RwLockWriteGuard` used through
924 /// `Deref`.
925 ///
926 /// # Panics
927 ///
928 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
929 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
930 pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'rwlock, U>, Self>
931 where
932 F: FnOnce(&mut T) -> Option<&mut U>,
933 U: ?Sized,
934 {
935 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
936 // was created, and have been upheld throughout `map` and/or `filter_map`.
937 // The signature of the closure guarantees that it will not "leak" the lifetime of the
938 // reference passed to it. If the closure panics, the guard will be dropped.
939 match f(unsafe { &mut *orig.lock.data.get() }) {
940 Some(data) => {
941 let data = NonNull::from(data);
942 let orig = ManuallyDrop::new(orig);
943 Ok(MappedRwLockWriteGuard {
944 data,
945 inner_lock: &orig.lock.inner,
946 poison_flag: &orig.lock.poison,
947 poison_guard: orig.poison.clone(),
948 _variance: PhantomData,
949 })
950 }
951 None => Err(orig),
952 }
953 }
954}
955
956impl<'rwlock, T: ?Sized> MappedRwLockReadGuard<'rwlock, T> {
957 /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data,
958 /// e.g. an enum variant.
959 ///
960 /// The `RwLock` is already locked for reading, so this cannot fail.
961 ///
962 /// This is an associated function that needs to be used as
963 /// `MappedRwLockReadGuard::map(...)`. A method would interfere with
964 /// methods of the same name on the contents of the `MappedRwLockReadGuard`
965 /// used through `Deref`.
966 ///
967 /// # Panics
968 ///
969 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be
970 /// poisoned.
971 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
972 pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockReadGuard<'rwlock, U>
973 where
974 F: FnOnce(&T) -> &U,
975 U: ?Sized,
976 {
977 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
978 // was created, and have been upheld throughout `map` and/or `filter_map`.
979 // The signature of the closure guarantees that it will not "leak" the lifetime of the
980 // reference passed to it. If the closure panics, the guard will be dropped.
981 let data = NonNull::from(f(unsafe { orig.data.as_ref() }));
982 let orig = ManuallyDrop::new(orig);
983 MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock }
984 }
985
986 /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data.
987 /// The original guard is returned as an `Err(...)` if the closure returns
988 /// `None`.
989 ///
990 /// The `RwLock` is already locked for reading, so this cannot fail.
991 ///
992 /// This is an associated function that needs to be used as
993 /// `MappedRwLockReadGuard::filter_map(...)`. A method would interfere with
994 /// methods of the same name on the contents of the `MappedRwLockReadGuard`
995 /// used through `Deref`.
996 ///
997 /// # Panics
998 ///
999 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be
1000 /// poisoned.
1001 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
1002 pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'rwlock, U>, Self>
1003 where
1004 F: FnOnce(&T) -> Option<&U>,
1005 U: ?Sized,
1006 {
1007 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
1008 // was created, and have been upheld throughout `map` and/or `filter_map`.
1009 // The signature of the closure guarantees that it will not "leak" the lifetime of the
1010 // reference passed to it. If the closure panics, the guard will be dropped.
1011 match f(unsafe { orig.data.as_ref() }) {
1012 Some(data) => {
1013 let data = NonNull::from(data);
1014 let orig = ManuallyDrop::new(orig);
1015 Ok(MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock })
1016 }
1017 None => Err(orig),
1018 }
1019 }
1020}
1021
1022impl<'rwlock, T: ?Sized> MappedRwLockWriteGuard<'rwlock, T> {
1023 /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data,
1024 /// e.g. an enum variant.
1025 ///
1026 /// The `RwLock` is already locked for writing, so this cannot fail.
1027 ///
1028 /// This is an associated function that needs to be used as
1029 /// `MappedRwLockWriteGuard::map(...)`. A method would interfere with
1030 /// methods of the same name on the contents of the `MappedRwLockWriteGuard`
1031 /// used through `Deref`.
1032 ///
1033 /// # Panics
1034 ///
1035 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
1036 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
1037 pub fn map<U, F>(mut orig: Self, f: F) -> MappedRwLockWriteGuard<'rwlock, U>
1038 where
1039 F: FnOnce(&mut T) -> &mut U,
1040 U: ?Sized,
1041 {
1042 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1043 // was created, and have been upheld throughout `map` and/or `filter_map`.
1044 // The signature of the closure guarantees that it will not "leak" the lifetime of the
1045 // reference passed to it. If the closure panics, the guard will be dropped.
1046 let data = NonNull::from(f(unsafe { orig.data.as_mut() }));
1047 let orig = ManuallyDrop::new(orig);
1048 MappedRwLockWriteGuard {
1049 data,
1050 inner_lock: orig.inner_lock,
1051 poison_flag: orig.poison_flag,
1052 poison_guard: orig.poison_guard.clone(),
1053 _variance: PhantomData,
1054 }
1055 }
1056
1057 /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data.
1058 /// The original guard is returned as an `Err(...)` if the closure returns
1059 /// `None`.
1060 ///
1061 /// The `RwLock` is already locked for writing, so this cannot fail.
1062 ///
1063 /// This is an associated function that needs to be used as
1064 /// `MappedRwLockWriteGuard::filter_map(...)`. A method would interfere with
1065 /// methods of the same name on the contents of the `MappedRwLockWriteGuard`
1066 /// used through `Deref`.
1067 ///
1068 /// # Panics
1069 ///
1070 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
1071 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
1072 pub fn filter_map<U, F>(
1073 mut orig: Self,
1074 f: F,
1075 ) -> Result<MappedRwLockWriteGuard<'rwlock, U>, Self>
1076 where
1077 F: FnOnce(&mut T) -> Option<&mut U>,
1078 U: ?Sized,
1079 {
1080 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1081 // was created, and have been upheld throughout `map` and/or `filter_map`.
1082 // The signature of the closure guarantees that it will not "leak" the lifetime of the
1083 // reference passed to it. If the closure panics, the guard will be dropped.
1084 match f(unsafe { orig.data.as_mut() }) {
1085 Some(data) => {
1086 let data = NonNull::from(data);
1087 let orig = ManuallyDrop::new(orig);
1088 Ok(MappedRwLockWriteGuard {
1089 data,
1090 inner_lock: orig.inner_lock,
1091 poison_flag: orig.poison_flag,
1092 poison_guard: orig.poison_guard.clone(),
1093 _variance: PhantomData,
1094 })
1095 }
1096 None => Err(orig),
1097 }
1098 }
1099}
1100
1101#[stable(feature = "rust1", since = "1.0.0")]
1102impl<T: ?Sized> Drop for RwLockReadGuard<'_, T> {
1103 fn drop(&mut self) {
1104 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when created.
1105 unsafe {
1106 self.inner_lock.read_unlock();
1107 }
1108 }
1109}
1110
1111#[stable(feature = "rust1", since = "1.0.0")]
1112impl<T: ?Sized> Drop for RwLockWriteGuard<'_, T> {
1113 fn drop(&mut self) {
1114 self.lock.poison.done(&self.poison);
1115 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when created.
1116 unsafe {
1117 self.lock.inner.write_unlock();
1118 }
1119 }
1120}
1121
1122#[unstable(feature = "mapped_lock_guards", issue = "117108")]
1123impl<T: ?Sized> Drop for MappedRwLockReadGuard<'_, T> {
1124 fn drop(&mut self) {
1125 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
1126 // was created, and have been upheld throughout `map` and/or `filter_map`.
1127 unsafe {
1128 self.inner_lock.read_unlock();
1129 }
1130 }
1131}
1132
1133#[unstable(feature = "mapped_lock_guards", issue = "117108")]
1134impl<T: ?Sized> Drop for MappedRwLockWriteGuard<'_, T> {
1135 fn drop(&mut self) {
1136 self.poison_flag.done(&self.poison_guard);
1137 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1138 // was created, and have been upheld throughout `map` and/or `filter_map`.
1139 unsafe {
1140 self.inner_lock.write_unlock();
1141 }
1142 }
1143}
1144
1145#[stable(feature = "rust1", since = "1.0.0")]
1146impl<T: ?Sized> Deref for RwLockReadGuard<'_, T> {
1147 type Target = T;
1148
1149 fn deref(&self) -> &T {
1150 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when created.
1151 unsafe { self.data.as_ref() }
1152 }
1153}
1154
1155#[stable(feature = "rust1", since = "1.0.0")]
1156impl<T: ?Sized> Deref for RwLockWriteGuard<'_, T> {
1157 type Target = T;
1158
1159 fn deref(&self) -> &T {
1160 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when created.
1161 unsafe { &*self.lock.data.get() }
1162 }
1163}
1164
1165#[stable(feature = "rust1", since = "1.0.0")]
1166impl<T: ?Sized> DerefMut for RwLockWriteGuard<'_, T> {
1167 fn deref_mut(&mut self) -> &mut T {
1168 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when created.
1169 unsafe { &mut *self.lock.data.get() }
1170 }
1171}
1172
1173#[unstable(feature = "mapped_lock_guards", issue = "117108")]
1174impl<T: ?Sized> Deref for MappedRwLockReadGuard<'_, T> {
1175 type Target = T;
1176
1177 fn deref(&self) -> &T {
1178 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
1179 // was created, and have been upheld throughout `map` and/or `filter_map`.
1180 unsafe { self.data.as_ref() }
1181 }
1182}
1183
1184#[unstable(feature = "mapped_lock_guards", issue = "117108")]
1185impl<T: ?Sized> Deref for MappedRwLockWriteGuard<'_, T> {
1186 type Target = T;
1187
1188 fn deref(&self) -> &T {
1189 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1190 // was created, and have been upheld throughout `map` and/or `filter_map`.
1191 unsafe { self.data.as_ref() }
1192 }
1193}
1194
1195#[unstable(feature = "mapped_lock_guards", issue = "117108")]
1196impl<T: ?Sized> DerefMut for MappedRwLockWriteGuard<'_, T> {
1197 fn deref_mut(&mut self) -> &mut T {
1198 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1199 // was created, and have been upheld throughout `map` and/or `filter_map`.
1200 unsafe { self.data.as_mut() }
1201 }
1202}
1203
1204#[stable(feature = "std_debug", since = "1.16.0")]
1205impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLockReadGuard<'_, T> {
1206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1207 (**self).fmt(f)
1208 }
1209}
1210
1211#[stable(feature = "std_guard_impls", since = "1.20.0")]
1212impl<T: ?Sized + fmt::Display> fmt::Display for RwLockReadGuard<'_, T> {
1213 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1214 (**self).fmt(f)
1215 }
1216}
1217
1218#[stable(feature = "std_debug", since = "1.16.0")]
1219impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLockWriteGuard<'_, T> {
1220 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1221 (**self).fmt(f)
1222 }
1223}
1224
1225#[stable(feature = "std_guard_impls", since = "1.20.0")]
1226impl<T: ?Sized + fmt::Display> fmt::Display for RwLockWriteGuard<'_, T> {
1227 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1228 (**self).fmt(f)
1229 }
1230}
1231
1232#[unstable(feature = "mapped_lock_guards", issue = "117108")]
1233impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedRwLockReadGuard<'_, T> {
1234 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1235 (**self).fmt(f)
1236 }
1237}
1238
1239#[unstable(feature = "mapped_lock_guards", issue = "117108")]
1240impl<T: ?Sized + fmt::Display> fmt::Display for MappedRwLockReadGuard<'_, T> {
1241 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1242 (**self).fmt(f)
1243 }
1244}
1245
1246#[unstable(feature = "mapped_lock_guards", issue = "117108")]
1247impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedRwLockWriteGuard<'_, T> {
1248 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1249 (**self).fmt(f)
1250 }
1251}
1252
1253#[unstable(feature = "mapped_lock_guards", issue = "117108")]
1254impl<T: ?Sized + fmt::Display> fmt::Display for MappedRwLockWriteGuard<'_, T> {
1255 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1256 (**self).fmt(f)
1257 }
1258}