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