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