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 [`try_map`] methods
151/// on [`RwLockReadGuard`].
152///
153/// [`map`]: RwLockReadGuard::map
154/// [`try_map`]: RwLockReadGuard::try_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 [`try_map`] methods
180/// on [`RwLockWriteGuard`].
181///
182/// [`map`]: RwLockWriteGuard::map
183/// [`try_map`]: RwLockWriteGuard::try_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
639#[stable(feature = "rust1", since = "1.0.0")]
640impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
641 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
642 let mut d = f.debug_struct("RwLock");
643 match self.try_read() {
644 Ok(guard) => {
645 d.field("data", &&*guard);
646 }
647 Err(TryLockError::Poisoned(err)) => {
648 d.field("data", &&**err.get_ref());
649 }
650 Err(TryLockError::WouldBlock) => {
651 d.field("data", &format_args!("<locked>"));
652 }
653 }
654 d.field("poisoned", &self.poison.get());
655 d.finish_non_exhaustive()
656 }
657}
658
659#[stable(feature = "rw_lock_default", since = "1.10.0")]
660impl<T: Default> Default for RwLock<T> {
661 /// Creates a new `RwLock<T>`, with the `Default` value for T.
662 fn default() -> RwLock<T> {
663 RwLock::new(Default::default())
664 }
665}
666
667#[stable(feature = "rw_lock_from", since = "1.24.0")]
668impl<T> From<T> for RwLock<T> {
669 /// Creates a new instance of an `RwLock<T>` which is unlocked.
670 /// This is equivalent to [`RwLock::new`].
671 fn from(t: T) -> Self {
672 RwLock::new(t)
673 }
674}
675
676impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
677 /// Creates a new instance of `RwLockReadGuard<T>` from a `RwLock<T>`.
678 ///
679 /// # Safety
680 ///
681 /// This function is safe if and only if the same thread has successfully and safely called
682 /// `lock.inner.read()`, `lock.inner.try_read()`, or `lock.inner.downgrade()` before
683 /// instantiating this object.
684 unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockReadGuard<'rwlock, T>> {
685 poison::map_result(lock.poison.borrow(), |()| RwLockReadGuard {
686 data: unsafe { NonNull::new_unchecked(lock.data.get()) },
687 inner_lock: &lock.inner,
688 })
689 }
690}
691
692impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
693 /// Creates a new instance of `RwLockWriteGuard<T>` from a `RwLock<T>`.
694 // SAFETY: if and only if `lock.inner.write()` (or `lock.inner.try_write()`) has been
695 // successfully called from the same thread before instantiating this object.
696 unsafe fn new(lock: &'rwlock RwLock<T>) -> LockResult<RwLockWriteGuard<'rwlock, T>> {
697 poison::map_result(lock.poison.guard(), |guard| RwLockWriteGuard { lock, poison: guard })
698 }
699}
700
701#[stable(feature = "std_debug", since = "1.16.0")]
702impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLockReadGuard<'_, T> {
703 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
704 (**self).fmt(f)
705 }
706}
707
708#[stable(feature = "std_guard_impls", since = "1.20.0")]
709impl<T: ?Sized + fmt::Display> fmt::Display for RwLockReadGuard<'_, T> {
710 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
711 (**self).fmt(f)
712 }
713}
714
715#[stable(feature = "std_debug", since = "1.16.0")]
716impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLockWriteGuard<'_, T> {
717 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
718 (**self).fmt(f)
719 }
720}
721
722#[stable(feature = "std_guard_impls", since = "1.20.0")]
723impl<T: ?Sized + fmt::Display> fmt::Display for RwLockWriteGuard<'_, T> {
724 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
725 (**self).fmt(f)
726 }
727}
728
729#[unstable(feature = "mapped_lock_guards", issue = "117108")]
730impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedRwLockReadGuard<'_, T> {
731 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
732 (**self).fmt(f)
733 }
734}
735
736#[unstable(feature = "mapped_lock_guards", issue = "117108")]
737impl<T: ?Sized + fmt::Display> fmt::Display for MappedRwLockReadGuard<'_, T> {
738 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
739 (**self).fmt(f)
740 }
741}
742
743#[unstable(feature = "mapped_lock_guards", issue = "117108")]
744impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedRwLockWriteGuard<'_, T> {
745 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
746 (**self).fmt(f)
747 }
748}
749
750#[unstable(feature = "mapped_lock_guards", issue = "117108")]
751impl<T: ?Sized + fmt::Display> fmt::Display for MappedRwLockWriteGuard<'_, T> {
752 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
753 (**self).fmt(f)
754 }
755}
756
757#[stable(feature = "rust1", since = "1.0.0")]
758impl<T: ?Sized> Deref for RwLockReadGuard<'_, T> {
759 type Target = T;
760
761 fn deref(&self) -> &T {
762 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when created.
763 unsafe { self.data.as_ref() }
764 }
765}
766
767#[stable(feature = "rust1", since = "1.0.0")]
768impl<T: ?Sized> Deref for RwLockWriteGuard<'_, T> {
769 type Target = T;
770
771 fn deref(&self) -> &T {
772 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when created.
773 unsafe { &*self.lock.data.get() }
774 }
775}
776
777#[stable(feature = "rust1", since = "1.0.0")]
778impl<T: ?Sized> DerefMut for RwLockWriteGuard<'_, T> {
779 fn deref_mut(&mut self) -> &mut T {
780 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when created.
781 unsafe { &mut *self.lock.data.get() }
782 }
783}
784
785#[unstable(feature = "mapped_lock_guards", issue = "117108")]
786impl<T: ?Sized> Deref for MappedRwLockReadGuard<'_, T> {
787 type Target = T;
788
789 fn deref(&self) -> &T {
790 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
791 // was created, and have been upheld throughout `map` and/or `try_map`.
792 unsafe { self.data.as_ref() }
793 }
794}
795
796#[unstable(feature = "mapped_lock_guards", issue = "117108")]
797impl<T: ?Sized> Deref for MappedRwLockWriteGuard<'_, T> {
798 type Target = T;
799
800 fn deref(&self) -> &T {
801 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
802 // was created, and have been upheld throughout `map` and/or `try_map`.
803 unsafe { self.data.as_ref() }
804 }
805}
806
807#[unstable(feature = "mapped_lock_guards", issue = "117108")]
808impl<T: ?Sized> DerefMut for MappedRwLockWriteGuard<'_, T> {
809 fn deref_mut(&mut self) -> &mut T {
810 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
811 // was created, and have been upheld throughout `map` and/or `try_map`.
812 unsafe { self.data.as_mut() }
813 }
814}
815
816#[stable(feature = "rust1", since = "1.0.0")]
817impl<T: ?Sized> Drop for RwLockReadGuard<'_, T> {
818 fn drop(&mut self) {
819 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when created.
820 unsafe {
821 self.inner_lock.read_unlock();
822 }
823 }
824}
825
826#[stable(feature = "rust1", since = "1.0.0")]
827impl<T: ?Sized> Drop for RwLockWriteGuard<'_, T> {
828 fn drop(&mut self) {
829 self.lock.poison.done(&self.poison);
830 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when created.
831 unsafe {
832 self.lock.inner.write_unlock();
833 }
834 }
835}
836
837#[unstable(feature = "mapped_lock_guards", issue = "117108")]
838impl<T: ?Sized> Drop for MappedRwLockReadGuard<'_, T> {
839 fn drop(&mut self) {
840 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
841 // was created, and have been upheld throughout `map` and/or `try_map`.
842 unsafe {
843 self.inner_lock.read_unlock();
844 }
845 }
846}
847
848#[unstable(feature = "mapped_lock_guards", issue = "117108")]
849impl<T: ?Sized> Drop for MappedRwLockWriteGuard<'_, T> {
850 fn drop(&mut self) {
851 self.poison_flag.done(&self.poison);
852 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
853 // was created, and have been upheld throughout `map` and/or `try_map`.
854 unsafe {
855 self.inner_lock.write_unlock();
856 }
857 }
858}
859
860impl<'a, T: ?Sized> RwLockReadGuard<'a, T> {
861 /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data, e.g.
862 /// an enum variant.
863 ///
864 /// The `RwLock` is already locked for reading, so this cannot fail.
865 ///
866 /// This is an associated function that needs to be used as
867 /// `RwLockReadGuard::map(...)`. A method would interfere with methods of
868 /// the same name on the contents of the `RwLockReadGuard` used through
869 /// `Deref`.
870 ///
871 /// # Panics
872 ///
873 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
874 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
875 pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockReadGuard<'a, U>
876 where
877 F: FnOnce(&T) -> &U,
878 U: ?Sized,
879 {
880 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
881 // was created, and have been upheld throughout `map` and/or `try_map`.
882 // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
883 // passed to it. If the closure panics, the guard will be dropped.
884 let data = NonNull::from(f(unsafe { orig.data.as_ref() }));
885 let orig = ManuallyDrop::new(orig);
886 MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock }
887 }
888
889 /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data. The
890 /// original guard is returned as an `Err(...)` if the closure returns
891 /// `None`.
892 ///
893 /// The `RwLock` is already locked for reading, so this cannot fail.
894 ///
895 /// This is an associated function that needs to be used as
896 /// `RwLockReadGuard::try_map(...)`. A method would interfere with methods
897 /// of the same name on the contents of the `RwLockReadGuard` used through
898 /// `Deref`.
899 ///
900 /// # Panics
901 ///
902 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
903 #[doc(alias = "filter_map")]
904 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
905 pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
906 where
907 F: FnOnce(&T) -> Option<&U>,
908 U: ?Sized,
909 {
910 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
911 // was created, and have been upheld throughout `map` and/or `try_map`.
912 // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
913 // passed to it. If the closure panics, the guard will be dropped.
914 match f(unsafe { orig.data.as_ref() }) {
915 Some(data) => {
916 let data = NonNull::from(data);
917 let orig = ManuallyDrop::new(orig);
918 Ok(MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock })
919 }
920 None => Err(orig),
921 }
922 }
923}
924
925impl<'a, T: ?Sized> MappedRwLockReadGuard<'a, T> {
926 /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data,
927 /// e.g. an enum variant.
928 ///
929 /// The `RwLock` is already locked for reading, so this cannot fail.
930 ///
931 /// This is an associated function that needs to be used as
932 /// `MappedRwLockReadGuard::map(...)`. A method would interfere with
933 /// methods of the same name on the contents of the `MappedRwLockReadGuard`
934 /// used through `Deref`.
935 ///
936 /// # Panics
937 ///
938 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
939 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
940 pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockReadGuard<'a, U>
941 where
942 F: FnOnce(&T) -> &U,
943 U: ?Sized,
944 {
945 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
946 // was created, and have been upheld throughout `map` and/or `try_map`.
947 // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
948 // passed to it. If the closure panics, the guard will be dropped.
949 let data = NonNull::from(f(unsafe { orig.data.as_ref() }));
950 let orig = ManuallyDrop::new(orig);
951 MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock }
952 }
953
954 /// Makes a [`MappedRwLockReadGuard`] for a component of the borrowed data.
955 /// The original guard is returned as an `Err(...)` if the closure returns
956 /// `None`.
957 ///
958 /// The `RwLock` is already locked for reading, so this cannot fail.
959 ///
960 /// This is an associated function that needs to be used as
961 /// `MappedRwLockReadGuard::try_map(...)`. A method would interfere with
962 /// methods of the same name on the contents of the `MappedRwLockReadGuard`
963 /// used through `Deref`.
964 ///
965 /// # Panics
966 ///
967 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
968 #[doc(alias = "filter_map")]
969 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
970 pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
971 where
972 F: FnOnce(&T) -> Option<&U>,
973 U: ?Sized,
974 {
975 // SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
976 // was created, and have been upheld throughout `map` and/or `try_map`.
977 // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
978 // passed to it. If the closure panics, the guard will be dropped.
979 match f(unsafe { orig.data.as_ref() }) {
980 Some(data) => {
981 let data = NonNull::from(data);
982 let orig = ManuallyDrop::new(orig);
983 Ok(MappedRwLockReadGuard { data, inner_lock: &orig.inner_lock })
984 }
985 None => Err(orig),
986 }
987 }
988}
989
990impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
991 /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data, e.g.
992 /// an enum variant.
993 ///
994 /// The `RwLock` is already locked for writing, so this cannot fail.
995 ///
996 /// This is an associated function that needs to be used as
997 /// `RwLockWriteGuard::map(...)`. A method would interfere with methods of
998 /// the same name on the contents of the `RwLockWriteGuard` used through
999 /// `Deref`.
1000 ///
1001 /// # Panics
1002 ///
1003 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
1004 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
1005 pub fn map<U, F>(orig: Self, f: F) -> MappedRwLockWriteGuard<'a, U>
1006 where
1007 F: FnOnce(&mut T) -> &mut U,
1008 U: ?Sized,
1009 {
1010 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1011 // was created, and have been upheld throughout `map` and/or `try_map`.
1012 // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
1013 // passed to it. If the closure panics, the guard will be dropped.
1014 let data = NonNull::from(f(unsafe { &mut *orig.lock.data.get() }));
1015 let orig = ManuallyDrop::new(orig);
1016 MappedRwLockWriteGuard {
1017 data,
1018 inner_lock: &orig.lock.inner,
1019 poison_flag: &orig.lock.poison,
1020 poison: orig.poison.clone(),
1021 _variance: PhantomData,
1022 }
1023 }
1024
1025 /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data. The
1026 /// original guard is returned as an `Err(...)` if the closure returns
1027 /// `None`.
1028 ///
1029 /// The `RwLock` is already locked for writing, so this cannot fail.
1030 ///
1031 /// This is an associated function that needs to be used as
1032 /// `RwLockWriteGuard::try_map(...)`. A method would interfere with methods
1033 /// of the same name on the contents of the `RwLockWriteGuard` used through
1034 /// `Deref`.
1035 ///
1036 /// # Panics
1037 ///
1038 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
1039 #[doc(alias = "filter_map")]
1040 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
1041 pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
1042 where
1043 F: FnOnce(&mut T) -> Option<&mut U>,
1044 U: ?Sized,
1045 {
1046 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1047 // was created, and have been upheld throughout `map` and/or `try_map`.
1048 // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
1049 // passed to it. If the closure panics, the guard will be dropped.
1050 match f(unsafe { &mut *orig.lock.data.get() }) {
1051 Some(data) => {
1052 let data = NonNull::from(data);
1053 let orig = ManuallyDrop::new(orig);
1054 Ok(MappedRwLockWriteGuard {
1055 data,
1056 inner_lock: &orig.lock.inner,
1057 poison_flag: &orig.lock.poison,
1058 poison: orig.poison.clone(),
1059 _variance: PhantomData,
1060 })
1061 }
1062 None => Err(orig),
1063 }
1064 }
1065
1066 /// Downgrades a write-locked `RwLockWriteGuard` into a read-locked [`RwLockReadGuard`].
1067 ///
1068 /// This method will atomically change the state of the [`RwLock`] from exclusive mode into
1069 /// shared mode. This means that it is impossible for a writing thread to get in between a
1070 /// thread calling `downgrade` and the same thread reading whatever it wrote while it had the
1071 /// [`RwLock`] in write mode.
1072 ///
1073 /// Note that since we have the `RwLockWriteGuard`, we know that the [`RwLock`] is already
1074 /// locked for writing, so this method cannot fail.
1075 ///
1076 /// # Example
1077 ///
1078 /// ```
1079 /// #![feature(rwlock_downgrade)]
1080 /// use std::sync::{Arc, RwLock, RwLockWriteGuard};
1081 ///
1082 /// // The inner value starts as 0.
1083 /// let rw = Arc::new(RwLock::new(0));
1084 ///
1085 /// // Put the lock in write mode.
1086 /// let mut main_write_guard = rw.write().unwrap();
1087 ///
1088 /// let evil = rw.clone();
1089 /// let handle = std::thread::spawn(move || {
1090 /// // This will not return until the main thread drops the `main_read_guard`.
1091 /// let mut evil_guard = evil.write().unwrap();
1092 ///
1093 /// assert_eq!(*evil_guard, 1);
1094 /// *evil_guard = 2;
1095 /// });
1096 ///
1097 /// // After spawning the writer thread, set the inner value to 1.
1098 /// *main_write_guard = 1;
1099 ///
1100 /// // Atomically downgrade the write guard into a read guard.
1101 /// let main_read_guard = RwLockWriteGuard::downgrade(main_write_guard);
1102 ///
1103 /// // Since `downgrade` is atomic, the writer thread cannot have set the inner value to 2.
1104 /// assert_eq!(*main_read_guard, 1, "`downgrade` was not atomic");
1105 ///
1106 /// // Clean up everything now
1107 /// drop(main_read_guard);
1108 /// handle.join().unwrap();
1109 ///
1110 /// let final_check = rw.read().unwrap();
1111 /// assert_eq!(*final_check, 2);
1112 /// ```
1113 #[unstable(feature = "rwlock_downgrade", issue = "128203")]
1114 pub fn downgrade(s: Self) -> RwLockReadGuard<'a, T> {
1115 let lock = s.lock;
1116
1117 // We don't want to call the destructor since that calls `write_unlock`.
1118 forget(s);
1119
1120 // SAFETY: We take ownership of a write guard, so we must already have the `RwLock` in write
1121 // mode, satisfying the `downgrade` contract.
1122 unsafe { lock.inner.downgrade() };
1123
1124 // SAFETY: We have just successfully called `downgrade`, so we fulfill the safety contract.
1125 unsafe { RwLockReadGuard::new(lock).unwrap_or_else(PoisonError::into_inner) }
1126 }
1127}
1128
1129impl<'a, T: ?Sized> MappedRwLockWriteGuard<'a, T> {
1130 /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data,
1131 /// e.g. an enum variant.
1132 ///
1133 /// The `RwLock` is already locked for writing, so this cannot fail.
1134 ///
1135 /// This is an associated function that needs to be used as
1136 /// `MappedRwLockWriteGuard::map(...)`. A method would interfere with
1137 /// methods of the same name on the contents of the `MappedRwLockWriteGuard`
1138 /// used through `Deref`.
1139 ///
1140 /// # Panics
1141 ///
1142 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
1143 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
1144 pub fn map<U, F>(mut orig: Self, f: F) -> MappedRwLockWriteGuard<'a, U>
1145 where
1146 F: FnOnce(&mut T) -> &mut U,
1147 U: ?Sized,
1148 {
1149 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1150 // was created, and have been upheld throughout `map` and/or `try_map`.
1151 // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
1152 // passed to it. If the closure panics, the guard will be dropped.
1153 let data = NonNull::from(f(unsafe { orig.data.as_mut() }));
1154 let orig = ManuallyDrop::new(orig);
1155 MappedRwLockWriteGuard {
1156 data,
1157 inner_lock: orig.inner_lock,
1158 poison_flag: orig.poison_flag,
1159 poison: orig.poison.clone(),
1160 _variance: PhantomData,
1161 }
1162 }
1163
1164 /// Makes a [`MappedRwLockWriteGuard`] for a component of the borrowed data.
1165 /// The original guard is returned as an `Err(...)` if the closure returns
1166 /// `None`.
1167 ///
1168 /// The `RwLock` is already locked for writing, so this cannot fail.
1169 ///
1170 /// This is an associated function that needs to be used as
1171 /// `MappedRwLockWriteGuard::try_map(...)`. A method would interfere with
1172 /// methods of the same name on the contents of the `MappedRwLockWriteGuard`
1173 /// used through `Deref`.
1174 ///
1175 /// # Panics
1176 ///
1177 /// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
1178 #[doc(alias = "filter_map")]
1179 #[unstable(feature = "mapped_lock_guards", issue = "117108")]
1180 pub fn try_map<U, F>(mut orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
1181 where
1182 F: FnOnce(&mut T) -> Option<&mut U>,
1183 U: ?Sized,
1184 {
1185 // SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
1186 // was created, and have been upheld throughout `map` and/or `try_map`.
1187 // The signature of the closure guarantees that it will not "leak" the lifetime of the reference
1188 // passed to it. If the closure panics, the guard will be dropped.
1189 match f(unsafe { orig.data.as_mut() }) {
1190 Some(data) => {
1191 let data = NonNull::from(data);
1192 let orig = ManuallyDrop::new(orig);
1193 Ok(MappedRwLockWriteGuard {
1194 data,
1195 inner_lock: orig.inner_lock,
1196 poison_flag: orig.poison_flag,
1197 poison: orig.poison.clone(),
1198 _variance: PhantomData,
1199 })
1200 }
1201 None => Err(orig),
1202 }
1203 }
1204}