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