lock_api/
rwlock.rs

1// Copyright 2016 Amanieu d'Antras
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use core::cell::UnsafeCell;
9use core::fmt;
10use core::marker::PhantomData;
11use core::mem;
12use core::ops::{Deref, DerefMut};
13
14#[cfg(feature = "arc_lock")]
15use alloc::sync::Arc;
16#[cfg(feature = "arc_lock")]
17use core::mem::ManuallyDrop;
18#[cfg(feature = "arc_lock")]
19use core::ptr;
20
21#[cfg(feature = "owning_ref")]
22use owning_ref::StableAddress;
23
24#[cfg(feature = "serde")]
25use serde::{Deserialize, Deserializer, Serialize, Serializer};
26
27/// Basic operations for a reader-writer lock.
28///
29/// Types implementing this trait can be used by `RwLock` to form a safe and
30/// fully-functioning `RwLock` type.
31///
32/// # Safety
33///
34/// Implementations of this trait must ensure that the `RwLock` is actually
35/// exclusive: an exclusive lock can't be acquired while an exclusive or shared
36/// lock exists, and a shared lock can't be acquire while an exclusive lock
37/// exists.
38pub unsafe trait RawRwLock {
39    /// Initial value for an unlocked `RwLock`.
40    // A “non-constant” const item is a legacy way to supply an initialized value to downstream
41    // static items. Can hopefully be replaced with `const fn new() -> Self` at some point.
42    #[allow(clippy::declare_interior_mutable_const)]
43    const INIT: Self;
44
45    /// Marker type which determines whether a lock guard should be `Send`. Use
46    /// one of the `GuardSend` or `GuardNoSend` helper types here.
47    type GuardMarker;
48
49    /// Acquires a shared lock, blocking the current thread until it is able to do so.
50    fn lock_shared(&self);
51
52    /// Attempts to acquire a shared lock without blocking.
53    fn try_lock_shared(&self) -> bool;
54
55    /// Releases a shared lock.
56    ///
57    /// # Safety
58    ///
59    /// This method may only be called if a shared lock is held in the current context.
60    unsafe fn unlock_shared(&self);
61
62    /// Acquires an exclusive lock, blocking the current thread until it is able to do so.
63    fn lock_exclusive(&self);
64
65    /// Attempts to acquire an exclusive lock without blocking.
66    fn try_lock_exclusive(&self) -> bool;
67
68    /// Releases an exclusive lock.
69    ///
70    /// # Safety
71    ///
72    /// This method may only be called if an exclusive lock is held in the current context.
73    unsafe fn unlock_exclusive(&self);
74
75    /// Checks if this `RwLock` is currently locked in any way.
76    #[inline]
77    fn is_locked(&self) -> bool {
78        let acquired_lock = self.try_lock_exclusive();
79        if acquired_lock {
80            // Safety: A lock was successfully acquired above.
81            unsafe {
82                self.unlock_exclusive();
83            }
84        }
85        !acquired_lock
86    }
87
88    /// Check if this `RwLock` is currently exclusively locked.
89    fn is_locked_exclusive(&self) -> bool {
90        let acquired_lock = self.try_lock_shared();
91        if acquired_lock {
92            // Safety: A shared lock was successfully acquired above.
93            unsafe {
94                self.unlock_shared();
95            }
96        }
97        !acquired_lock
98    }
99}
100
101/// Additional methods for `RwLock`s which support fair unlocking.
102///
103/// Fair unlocking means that a lock is handed directly over to the next waiting
104/// thread if there is one, without giving other threads the opportunity to
105/// "steal" the lock in the meantime. This is typically slower than unfair
106/// unlocking, but may be necessary in certain circumstances.
107pub unsafe trait RawRwLockFair: RawRwLock {
108    /// Releases a shared lock using a fair unlock protocol.
109    ///
110    /// # Safety
111    ///
112    /// This method may only be called if a shared lock is held in the current context.
113    unsafe fn unlock_shared_fair(&self);
114
115    /// Releases an exclusive lock using a fair unlock protocol.
116    ///
117    /// # Safety
118    ///
119    /// This method may only be called if an exclusive lock is held in the current context.
120    unsafe fn unlock_exclusive_fair(&self);
121
122    /// Temporarily yields a shared lock to a waiting thread if there is one.
123    ///
124    /// This method is functionally equivalent to calling `unlock_shared_fair` followed
125    /// by `lock_shared`, however it can be much more efficient in the case where there
126    /// are no waiting threads.
127    ///
128    /// # Safety
129    ///
130    /// This method may only be called if a shared lock is held in the current context.
131    unsafe fn bump_shared(&self) {
132        self.unlock_shared_fair();
133        self.lock_shared();
134    }
135
136    /// Temporarily yields an exclusive lock to a waiting thread if there is one.
137    ///
138    /// This method is functionally equivalent to calling `unlock_exclusive_fair` followed
139    /// by `lock_exclusive`, however it can be much more efficient in the case where there
140    /// are no waiting threads.
141    ///
142    /// # Safety
143    ///
144    /// This method may only be called if an exclusive lock is held in the current context.
145    unsafe fn bump_exclusive(&self) {
146        self.unlock_exclusive_fair();
147        self.lock_exclusive();
148    }
149}
150
151/// Additional methods for `RwLock`s which support atomically downgrading an
152/// exclusive lock to a shared lock.
153pub unsafe trait RawRwLockDowngrade: RawRwLock {
154    /// Atomically downgrades an exclusive lock into a shared lock without
155    /// allowing any thread to take an exclusive lock in the meantime.
156    ///
157    /// # Safety
158    ///
159    /// This method may only be called if an exclusive lock is held in the current context.
160    unsafe fn downgrade(&self);
161}
162
163/// Additional methods for `RwLock`s which support locking with timeouts.
164///
165/// The `Duration` and `Instant` types are specified as associated types so that
166/// this trait is usable even in `no_std` environments.
167pub unsafe trait RawRwLockTimed: RawRwLock {
168    /// Duration type used for `try_lock_for`.
169    type Duration;
170
171    /// Instant type used for `try_lock_until`.
172    type Instant;
173
174    /// Attempts to acquire a shared lock until a timeout is reached.
175    fn try_lock_shared_for(&self, timeout: Self::Duration) -> bool;
176
177    /// Attempts to acquire a shared lock until a timeout is reached.
178    fn try_lock_shared_until(&self, timeout: Self::Instant) -> bool;
179
180    /// Attempts to acquire an exclusive lock until a timeout is reached.
181    fn try_lock_exclusive_for(&self, timeout: Self::Duration) -> bool;
182
183    /// Attempts to acquire an exclusive lock until a timeout is reached.
184    fn try_lock_exclusive_until(&self, timeout: Self::Instant) -> bool;
185}
186
187/// Additional methods for `RwLock`s which support recursive read locks.
188///
189/// These are guaranteed to succeed without blocking if
190/// another read lock is held at the time of the call. This allows a thread
191/// to recursively lock a `RwLock`. However using this method can cause
192/// writers to starve since readers no longer block if a writer is waiting
193/// for the lock.
194pub unsafe trait RawRwLockRecursive: RawRwLock {
195    /// Acquires a shared lock without deadlocking in case of a recursive lock.
196    fn lock_shared_recursive(&self);
197
198    /// Attempts to acquire a shared lock without deadlocking in case of a recursive lock.
199    fn try_lock_shared_recursive(&self) -> bool;
200}
201
202/// Additional methods for `RwLock`s which support recursive read locks and timeouts.
203pub unsafe trait RawRwLockRecursiveTimed: RawRwLockRecursive + RawRwLockTimed {
204    /// Attempts to acquire a shared lock until a timeout is reached, without
205    /// deadlocking in case of a recursive lock.
206    fn try_lock_shared_recursive_for(&self, timeout: Self::Duration) -> bool;
207
208    /// Attempts to acquire a shared lock until a timeout is reached, without
209    /// deadlocking in case of a recursive lock.
210    fn try_lock_shared_recursive_until(&self, timeout: Self::Instant) -> bool;
211}
212
213/// Additional methods for `RwLock`s which support atomically upgrading a shared
214/// lock to an exclusive lock.
215///
216/// This requires acquiring a special "upgradable read lock" instead of a
217/// normal shared lock. There may only be one upgradable lock at any time,
218/// otherwise deadlocks could occur when upgrading.
219pub unsafe trait RawRwLockUpgrade: RawRwLock {
220    /// Acquires an upgradable lock, blocking the current thread until it is able to do so.
221    fn lock_upgradable(&self);
222
223    /// Attempts to acquire an upgradable lock without blocking.
224    fn try_lock_upgradable(&self) -> bool;
225
226    /// Releases an upgradable lock.
227    ///
228    /// # Safety
229    ///
230    /// This method may only be called if an upgradable lock is held in the current context.
231    unsafe fn unlock_upgradable(&self);
232
233    /// Upgrades an upgradable lock to an exclusive lock.
234    ///
235    /// # Safety
236    ///
237    /// This method may only be called if an upgradable lock is held in the current context.
238    unsafe fn upgrade(&self);
239
240    /// Attempts to upgrade an upgradable lock to an exclusive lock without
241    /// blocking.
242    ///
243    /// # Safety
244    ///
245    /// This method may only be called if an upgradable lock is held in the current context.
246    unsafe fn try_upgrade(&self) -> bool;
247}
248
249/// Additional methods for `RwLock`s which support upgradable locks and fair
250/// unlocking.
251pub unsafe trait RawRwLockUpgradeFair: RawRwLockUpgrade + RawRwLockFair {
252    /// Releases an upgradable lock using a fair unlock protocol.
253    ///
254    /// # Safety
255    ///
256    /// This method may only be called if an upgradable lock is held in the current context.
257    unsafe fn unlock_upgradable_fair(&self);
258
259    /// Temporarily yields an upgradable lock to a waiting thread if there is one.
260    ///
261    /// This method is functionally equivalent to calling `unlock_upgradable_fair` followed
262    /// by `lock_upgradable`, however it can be much more efficient in the case where there
263    /// are no waiting threads.
264    ///
265    /// # Safety
266    ///
267    /// This method may only be called if an upgradable lock is held in the current context.
268    unsafe fn bump_upgradable(&self) {
269        self.unlock_upgradable_fair();
270        self.lock_upgradable();
271    }
272}
273
274/// Additional methods for `RwLock`s which support upgradable locks and lock
275/// downgrading.
276pub unsafe trait RawRwLockUpgradeDowngrade: RawRwLockUpgrade + RawRwLockDowngrade {
277    /// Downgrades an upgradable lock to a shared lock.
278    ///
279    /// # Safety
280    ///
281    /// This method may only be called if an upgradable lock is held in the current context.
282    unsafe fn downgrade_upgradable(&self);
283
284    /// Downgrades an exclusive lock to an upgradable lock.
285    ///
286    /// # Safety
287    ///
288    /// This method may only be called if an exclusive lock is held in the current context.
289    unsafe fn downgrade_to_upgradable(&self);
290}
291
292/// Additional methods for `RwLock`s which support upgradable locks and locking
293/// with timeouts.
294pub unsafe trait RawRwLockUpgradeTimed: RawRwLockUpgrade + RawRwLockTimed {
295    /// Attempts to acquire an upgradable lock until a timeout is reached.
296    fn try_lock_upgradable_for(&self, timeout: Self::Duration) -> bool;
297
298    /// Attempts to acquire an upgradable lock until a timeout is reached.
299    fn try_lock_upgradable_until(&self, timeout: Self::Instant) -> bool;
300
301    /// Attempts to upgrade an upgradable lock to an exclusive lock until a
302    /// timeout is reached.
303    ///
304    /// # Safety
305    ///
306    /// This method may only be called if an upgradable lock is held in the current context.
307    unsafe fn try_upgrade_for(&self, timeout: Self::Duration) -> bool;
308
309    /// Attempts to upgrade an upgradable lock to an exclusive lock until a
310    /// timeout is reached.
311    ///
312    /// # Safety
313    ///
314    /// This method may only be called if an upgradable lock is held in the current context.
315    unsafe fn try_upgrade_until(&self, timeout: Self::Instant) -> bool;
316}
317
318/// A reader-writer lock
319///
320/// This type of lock allows a number of readers or at most one writer at any
321/// point in time. The write portion of this lock typically allows modification
322/// of the underlying data (exclusive access) and the read portion of this lock
323/// typically allows for read-only access (shared access).
324///
325/// The type parameter `T` represents the data that this lock protects. It is
326/// required that `T` satisfies `Send` to be shared across threads and `Sync` to
327/// allow concurrent access through readers. The RAII guards returned from the
328/// locking methods implement `Deref` (and `DerefMut` for the `write` methods)
329/// to allow access to the contained of the lock.
330pub struct RwLock<R, T: ?Sized> {
331    raw: R,
332    data: UnsafeCell<T>,
333}
334
335// Copied and modified from serde
336#[cfg(feature = "serde")]
337impl<R, T> Serialize for RwLock<R, T>
338where
339    R: RawRwLock,
340    T: Serialize + ?Sized,
341{
342    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
343    where
344        S: Serializer,
345    {
346        self.read().serialize(serializer)
347    }
348}
349
350#[cfg(feature = "serde")]
351impl<'de, R, T> Deserialize<'de> for RwLock<R, T>
352where
353    R: RawRwLock,
354    T: Deserialize<'de> + ?Sized,
355{
356    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
357    where
358        D: Deserializer<'de>,
359    {
360        Deserialize::deserialize(deserializer).map(RwLock::new)
361    }
362}
363
364unsafe impl<R: RawRwLock + Send, T: ?Sized + Send> Send for RwLock<R, T> {}
365unsafe impl<R: RawRwLock + Sync, T: ?Sized + Send + Sync> Sync for RwLock<R, T> {}
366
367impl<R: RawRwLock, T> RwLock<R, T> {
368    /// Creates a new instance of an `RwLock<T>` which is unlocked.
369    #[cfg(has_const_fn_trait_bound)]
370    #[inline]
371    pub const fn new(val: T) -> RwLock<R, T> {
372        RwLock {
373            data: UnsafeCell::new(val),
374            raw: R::INIT,
375        }
376    }
377
378    /// Creates a new instance of an `RwLock<T>` which is unlocked.
379    #[cfg(not(has_const_fn_trait_bound))]
380    #[inline]
381    pub fn new(val: T) -> RwLock<R, T> {
382        RwLock {
383            data: UnsafeCell::new(val),
384            raw: R::INIT,
385        }
386    }
387
388    /// Consumes this `RwLock`, returning the underlying data.
389    #[inline]
390    #[allow(unused_unsafe)]
391    pub fn into_inner(self) -> T {
392        unsafe { self.data.into_inner() }
393    }
394}
395
396impl<R, T> RwLock<R, T> {
397    /// Creates a new new instance of an `RwLock<T>` based on a pre-existing
398    /// `RawRwLock<T>`.
399    #[inline]
400    pub const fn from_raw(raw_rwlock: R, val: T) -> RwLock<R, T> {
401        RwLock {
402            data: UnsafeCell::new(val),
403            raw: raw_rwlock,
404        }
405    }
406
407    /// Creates a new new instance of an `RwLock<T>` based on a pre-existing
408    /// `RawRwLock<T>`.
409    ///
410    /// This allows creating a `RwLock<T>` in a constant context on stable
411    /// Rust.
412    ///
413    /// This method is a legacy alias for [`from_raw`](Self::from_raw).
414    #[inline]
415    pub const fn const_new(raw_rwlock: R, val: T) -> RwLock<R, T> {
416        Self::from_raw(raw_rwlock, val)
417    }
418}
419
420impl<R: RawRwLock, T: ?Sized> RwLock<R, T> {
421    /// Creates a new `RwLockReadGuard` without checking if the lock is held.
422    ///
423    /// # Safety
424    ///
425    /// This method must only be called if the thread logically holds a read lock.
426    ///
427    /// This function does not increment the read count of the lock. Calling this function when a
428    /// guard has already been produced is undefined behaviour unless the guard was forgotten
429    /// with `mem::forget`.
430    #[inline]
431    pub unsafe fn make_read_guard_unchecked(&self) -> RwLockReadGuard<'_, R, T> {
432        RwLockReadGuard {
433            rwlock: self,
434            marker: PhantomData,
435        }
436    }
437
438    /// Creates a new `RwLockReadGuard` without checking if the lock is held.
439    ///
440    /// # Safety
441    ///
442    /// This method must only be called if the thread logically holds a write lock.
443    ///
444    /// Calling this function when a guard has already been produced is undefined behaviour unless
445    /// the guard was forgotten with `mem::forget`.
446    #[inline]
447    pub unsafe fn make_write_guard_unchecked(&self) -> RwLockWriteGuard<'_, R, T> {
448        RwLockWriteGuard {
449            rwlock: self,
450            marker: PhantomData,
451        }
452    }
453
454    /// Locks this `RwLock` with shared read access, blocking the current thread
455    /// until it can be acquired.
456    ///
457    /// The calling thread will be blocked until there are no more writers which
458    /// hold the lock. There may be other readers currently inside the lock when
459    /// this method returns.
460    ///
461    /// Note that attempts to recursively acquire a read lock on a `RwLock` when
462    /// the current thread already holds one may result in a deadlock.
463    ///
464    /// Returns an RAII guard which will release this thread's shared access
465    /// once it is dropped.
466    #[inline]
467    pub fn read(&self) -> RwLockReadGuard<'_, R, T> {
468        self.raw.lock_shared();
469        // SAFETY: The lock is held, as required.
470        unsafe { self.make_read_guard_unchecked() }
471    }
472
473    /// Attempts to acquire this `RwLock` with shared read access.
474    ///
475    /// If the access could not be granted at this time, then `None` is returned.
476    /// Otherwise, an RAII guard is returned which will release the shared access
477    /// when it is dropped.
478    ///
479    /// This function does not block.
480    #[inline]
481    pub fn try_read(&self) -> Option<RwLockReadGuard<'_, R, T>> {
482        if self.raw.try_lock_shared() {
483            // SAFETY: The lock is held, as required.
484            Some(unsafe { self.make_read_guard_unchecked() })
485        } else {
486            None
487        }
488    }
489
490    /// Locks this `RwLock` with exclusive write access, blocking the current
491    /// thread until it can be acquired.
492    ///
493    /// This function will not return while other writers or other readers
494    /// currently have access to the lock.
495    ///
496    /// Returns an RAII guard which will drop the write access of this `RwLock`
497    /// when dropped.
498    #[inline]
499    pub fn write(&self) -> RwLockWriteGuard<'_, R, T> {
500        self.raw.lock_exclusive();
501        // SAFETY: The lock is held, as required.
502        unsafe { self.make_write_guard_unchecked() }
503    }
504
505    /// Attempts to lock this `RwLock` with exclusive write access.
506    ///
507    /// If the lock could not be acquired at this time, then `None` is returned.
508    /// Otherwise, an RAII guard is returned which will release the lock when
509    /// it is dropped.
510    ///
511    /// This function does not block.
512    #[inline]
513    pub fn try_write(&self) -> Option<RwLockWriteGuard<'_, R, T>> {
514        if self.raw.try_lock_exclusive() {
515            // SAFETY: The lock is held, as required.
516            Some(unsafe { self.make_write_guard_unchecked() })
517        } else {
518            None
519        }
520    }
521
522    /// Returns a mutable reference to the underlying data.
523    ///
524    /// Since this call borrows the `RwLock` mutably, no actual locking needs to
525    /// take place---the mutable borrow statically guarantees no locks exist.
526    #[inline]
527    pub fn get_mut(&mut self) -> &mut T {
528        unsafe { &mut *self.data.get() }
529    }
530
531    /// Checks whether this `RwLock` is currently locked in any way.
532    #[inline]
533    pub fn is_locked(&self) -> bool {
534        self.raw.is_locked()
535    }
536
537    /// Check if this `RwLock` is currently exclusively locked.
538    #[inline]
539    pub fn is_locked_exclusive(&self) -> bool {
540        self.raw.is_locked_exclusive()
541    }
542
543    /// Forcibly unlocks a read lock.
544    ///
545    /// This is useful when combined with `mem::forget` to hold a lock without
546    /// the need to maintain a `RwLockReadGuard` object alive, for example when
547    /// dealing with FFI.
548    ///
549    /// # Safety
550    ///
551    /// This method must only be called if the current thread logically owns a
552    /// `RwLockReadGuard` but that guard has be discarded using `mem::forget`.
553    /// Behavior is undefined if a rwlock is read-unlocked when not read-locked.
554    #[inline]
555    pub unsafe fn force_unlock_read(&self) {
556        self.raw.unlock_shared();
557    }
558
559    /// Forcibly unlocks a write lock.
560    ///
561    /// This is useful when combined with `mem::forget` to hold a lock without
562    /// the need to maintain a `RwLockWriteGuard` object alive, for example when
563    /// dealing with FFI.
564    ///
565    /// # Safety
566    ///
567    /// This method must only be called if the current thread logically owns a
568    /// `RwLockWriteGuard` but that guard has be discarded using `mem::forget`.
569    /// Behavior is undefined if a rwlock is write-unlocked when not write-locked.
570    #[inline]
571    pub unsafe fn force_unlock_write(&self) {
572        self.raw.unlock_exclusive();
573    }
574
575    /// Returns the underlying raw reader-writer lock object.
576    ///
577    /// Note that you will most likely need to import the `RawRwLock` trait from
578    /// `lock_api` to be able to call functions on the raw
579    /// reader-writer lock.
580    ///
581    /// # Safety
582    ///
583    /// This method is unsafe because it allows unlocking a mutex while
584    /// still holding a reference to a lock guard.
585    pub unsafe fn raw(&self) -> &R {
586        &self.raw
587    }
588
589    /// Returns a raw pointer to the underlying data.
590    ///
591    /// This is useful when combined with `mem::forget` to hold a lock without
592    /// the need to maintain a `RwLockReadGuard` or `RwLockWriteGuard` object
593    /// alive, for example when dealing with FFI.
594    ///
595    /// # Safety
596    ///
597    /// You must ensure that there are no data races when dereferencing the
598    /// returned pointer, for example if the current thread logically owns a
599    /// `RwLockReadGuard` or `RwLockWriteGuard` but that guard has been discarded
600    /// using `mem::forget`.
601    #[inline]
602    pub fn data_ptr(&self) -> *mut T {
603        self.data.get()
604    }
605
606    /// Creates a new `RwLockReadGuard` without checking if the lock is held.
607    ///
608    /// # Safety
609    ///
610    /// This method must only be called if the thread logically holds a read lock.
611    ///
612    /// This function does not increment the read count of the lock. Calling this function when a
613    /// guard has already been produced is undefined behaviour unless the guard was forgotten
614    /// with `mem::forget`.`
615    #[cfg(feature = "arc_lock")]
616    #[inline]
617    pub unsafe fn make_arc_read_guard_unchecked(self: &Arc<Self>) -> ArcRwLockReadGuard<R, T> {
618        ArcRwLockReadGuard {
619            rwlock: self.clone(),
620            marker: PhantomData,
621        }
622    }
623
624    /// Creates a new `RwLockWriteGuard` without checking if the lock is held.
625    ///
626    /// # Safety
627    ///
628    /// This method must only be called if the thread logically holds a write lock.
629    ///
630    /// Calling this function when a guard has already been produced is undefined behaviour unless
631    /// the guard was forgotten with `mem::forget`.
632    #[cfg(feature = "arc_lock")]
633    #[inline]
634    pub unsafe fn make_arc_write_guard_unchecked(self: &Arc<Self>) -> ArcRwLockWriteGuard<R, T> {
635        ArcRwLockWriteGuard {
636            rwlock: self.clone(),
637            marker: PhantomData,
638        }
639    }
640
641    /// Locks this `RwLock` with read access, through an `Arc`.
642    ///
643    /// This method is similar to the `read` method; however, it requires the `RwLock` to be inside of an `Arc`
644    /// and the resulting read guard has no lifetime requirements.
645    #[cfg(feature = "arc_lock")]
646    #[inline]
647    pub fn read_arc(self: &Arc<Self>) -> ArcRwLockReadGuard<R, T> {
648        self.raw.lock_shared();
649        // SAFETY: locking guarantee is upheld
650        unsafe { self.make_arc_read_guard_unchecked() }
651    }
652
653    /// Attempts to lock this `RwLock` with read access, through an `Arc`.
654    ///
655    /// This method is similar to the `try_read` method; however, it requires the `RwLock` to be inside of an
656    /// `Arc` and the resulting read guard has no lifetime requirements.
657    #[cfg(feature = "arc_lock")]
658    #[inline]
659    pub fn try_read_arc(self: &Arc<Self>) -> Option<ArcRwLockReadGuard<R, T>> {
660        if self.raw.try_lock_shared() {
661            // SAFETY: locking guarantee is upheld
662            Some(unsafe { self.make_arc_read_guard_unchecked() })
663        } else {
664            None
665        }
666    }
667
668    /// Locks this `RwLock` with write access, through an `Arc`.
669    ///
670    /// This method is similar to the `write` method; however, it requires the `RwLock` to be inside of an `Arc`
671    /// and the resulting write guard has no lifetime requirements.
672    #[cfg(feature = "arc_lock")]
673    #[inline]
674    pub fn write_arc(self: &Arc<Self>) -> ArcRwLockWriteGuard<R, T> {
675        self.raw.lock_exclusive();
676        // SAFETY: locking guarantee is upheld
677        unsafe { self.make_arc_write_guard_unchecked() }
678    }
679
680    /// Attempts to lock this `RwLock` with writ access, through an `Arc`.
681    ///
682    /// This method is similar to the `try_write` method; however, it requires the `RwLock` to be inside of an
683    /// `Arc` and the resulting write guard has no lifetime requirements.
684    #[cfg(feature = "arc_lock")]
685    #[inline]
686    pub fn try_write_arc(self: &Arc<Self>) -> Option<ArcRwLockWriteGuard<R, T>> {
687        if self.raw.try_lock_exclusive() {
688            // SAFETY: locking guarantee is upheld
689            Some(unsafe { self.make_arc_write_guard_unchecked() })
690        } else {
691            None
692        }
693    }
694}
695
696impl<R: RawRwLockFair, T: ?Sized> RwLock<R, T> {
697    /// Forcibly unlocks a read lock using a fair unlock protocol.
698    ///
699    /// This is useful when combined with `mem::forget` to hold a lock without
700    /// the need to maintain a `RwLockReadGuard` object alive, for example when
701    /// dealing with FFI.
702    ///
703    /// # Safety
704    ///
705    /// This method must only be called if the current thread logically owns a
706    /// `RwLockReadGuard` but that guard has be discarded using `mem::forget`.
707    /// Behavior is undefined if a rwlock is read-unlocked when not read-locked.
708    #[inline]
709    pub unsafe fn force_unlock_read_fair(&self) {
710        self.raw.unlock_shared_fair();
711    }
712
713    /// Forcibly unlocks a write lock using a fair unlock protocol.
714    ///
715    /// This is useful when combined with `mem::forget` to hold a lock without
716    /// the need to maintain a `RwLockWriteGuard` object alive, for example when
717    /// dealing with FFI.
718    ///
719    /// # Safety
720    ///
721    /// This method must only be called if the current thread logically owns a
722    /// `RwLockWriteGuard` but that guard has be discarded using `mem::forget`.
723    /// Behavior is undefined if a rwlock is write-unlocked when not write-locked.
724    #[inline]
725    pub unsafe fn force_unlock_write_fair(&self) {
726        self.raw.unlock_exclusive_fair();
727    }
728}
729
730impl<R: RawRwLockTimed, T: ?Sized> RwLock<R, T> {
731    /// Attempts to acquire this `RwLock` with shared read access until a timeout
732    /// is reached.
733    ///
734    /// If the access could not be granted before the timeout expires, then
735    /// `None` is returned. Otherwise, an RAII guard is returned which will
736    /// release the shared access when it is dropped.
737    #[inline]
738    pub fn try_read_for(&self, timeout: R::Duration) -> Option<RwLockReadGuard<'_, R, T>> {
739        if self.raw.try_lock_shared_for(timeout) {
740            // SAFETY: The lock is held, as required.
741            Some(unsafe { self.make_read_guard_unchecked() })
742        } else {
743            None
744        }
745    }
746
747    /// Attempts to acquire this `RwLock` with shared read access until a timeout
748    /// is reached.
749    ///
750    /// If the access could not be granted before the timeout expires, then
751    /// `None` is returned. Otherwise, an RAII guard is returned which will
752    /// release the shared access when it is dropped.
753    #[inline]
754    pub fn try_read_until(&self, timeout: R::Instant) -> Option<RwLockReadGuard<'_, R, T>> {
755        if self.raw.try_lock_shared_until(timeout) {
756            // SAFETY: The lock is held, as required.
757            Some(unsafe { self.make_read_guard_unchecked() })
758        } else {
759            None
760        }
761    }
762
763    /// Attempts to acquire this `RwLock` with exclusive write access until a
764    /// timeout is reached.
765    ///
766    /// If the access could not be granted before the timeout expires, then
767    /// `None` is returned. Otherwise, an RAII guard is returned which will
768    /// release the exclusive access when it is dropped.
769    #[inline]
770    pub fn try_write_for(&self, timeout: R::Duration) -> Option<RwLockWriteGuard<'_, R, T>> {
771        if self.raw.try_lock_exclusive_for(timeout) {
772            // SAFETY: The lock is held, as required.
773            Some(unsafe { self.make_write_guard_unchecked() })
774        } else {
775            None
776        }
777    }
778
779    /// Attempts to acquire this `RwLock` with exclusive write access until a
780    /// timeout is reached.
781    ///
782    /// If the access could not be granted before the timeout expires, then
783    /// `None` is returned. Otherwise, an RAII guard is returned which will
784    /// release the exclusive access when it is dropped.
785    #[inline]
786    pub fn try_write_until(&self, timeout: R::Instant) -> Option<RwLockWriteGuard<'_, R, T>> {
787        if self.raw.try_lock_exclusive_until(timeout) {
788            // SAFETY: The lock is held, as required.
789            Some(unsafe { self.make_write_guard_unchecked() })
790        } else {
791            None
792        }
793    }
794
795    /// Attempts to acquire this `RwLock` with read access until a timeout is reached, through an `Arc`.
796    ///
797    /// This method is similar to the `try_read_for` method; however, it requires the `RwLock` to be inside of an
798    /// `Arc` and the resulting read guard has no lifetime requirements.
799    #[cfg(feature = "arc_lock")]
800    #[inline]
801    pub fn try_read_arc_for(
802        self: &Arc<Self>,
803        timeout: R::Duration,
804    ) -> Option<ArcRwLockReadGuard<R, T>> {
805        if self.raw.try_lock_shared_for(timeout) {
806            // SAFETY: locking guarantee is upheld
807            Some(unsafe { self.make_arc_read_guard_unchecked() })
808        } else {
809            None
810        }
811    }
812
813    /// Attempts to acquire this `RwLock` with read access until a timeout is reached, through an `Arc`.
814    ///
815    /// This method is similar to the `try_read_until` method; however, it requires the `RwLock` to be inside of
816    /// an `Arc` and the resulting read guard has no lifetime requirements.
817    #[cfg(feature = "arc_lock")]
818    #[inline]
819    pub fn try_read_arc_until(
820        self: &Arc<Self>,
821        timeout: R::Instant,
822    ) -> Option<ArcRwLockReadGuard<R, T>> {
823        if self.raw.try_lock_shared_until(timeout) {
824            // SAFETY: locking guarantee is upheld
825            Some(unsafe { self.make_arc_read_guard_unchecked() })
826        } else {
827            None
828        }
829    }
830
831    /// Attempts to acquire this `RwLock` with write access until a timeout is reached, through an `Arc`.
832    ///
833    /// This method is similar to the `try_write_for` method; however, it requires the `RwLock` to be inside of
834    /// an `Arc` and the resulting write guard has no lifetime requirements.
835    #[cfg(feature = "arc_lock")]
836    #[inline]
837    pub fn try_write_arc_for(
838        self: &Arc<Self>,
839        timeout: R::Duration,
840    ) -> Option<ArcRwLockWriteGuard<R, T>> {
841        if self.raw.try_lock_exclusive_for(timeout) {
842            // SAFETY: locking guarantee is upheld
843            Some(unsafe { self.make_arc_write_guard_unchecked() })
844        } else {
845            None
846        }
847    }
848
849    /// Attempts to acquire this `RwLock` with read access until a timeout is reached, through an `Arc`.
850    ///
851    /// This method is similar to the `try_write_until` method; however, it requires the `RwLock` to be inside of
852    /// an `Arc` and the resulting read guard has no lifetime requirements.
853    #[cfg(feature = "arc_lock")]
854    #[inline]
855    pub fn try_write_arc_until(
856        self: &Arc<Self>,
857        timeout: R::Instant,
858    ) -> Option<ArcRwLockWriteGuard<R, T>> {
859        if self.raw.try_lock_exclusive_until(timeout) {
860            // SAFETY: locking guarantee is upheld
861            Some(unsafe { self.make_arc_write_guard_unchecked() })
862        } else {
863            None
864        }
865    }
866}
867
868impl<R: RawRwLockRecursive, T: ?Sized> RwLock<R, T> {
869    /// Locks this `RwLock` with shared read access, blocking the current thread
870    /// until it can be acquired.
871    ///
872    /// The calling thread will be blocked until there are no more writers which
873    /// hold the lock. There may be other readers currently inside the lock when
874    /// this method returns.
875    ///
876    /// Unlike `read`, this method is guaranteed to succeed without blocking if
877    /// another read lock is held at the time of the call. This allows a thread
878    /// to recursively lock a `RwLock`. However using this method can cause
879    /// writers to starve since readers no longer block if a writer is waiting
880    /// for the lock.
881    ///
882    /// Returns an RAII guard which will release this thread's shared access
883    /// once it is dropped.
884    #[inline]
885    pub fn read_recursive(&self) -> RwLockReadGuard<'_, R, T> {
886        self.raw.lock_shared_recursive();
887        // SAFETY: The lock is held, as required.
888        unsafe { self.make_read_guard_unchecked() }
889    }
890
891    /// Attempts to acquire this `RwLock` with shared read access.
892    ///
893    /// If the access could not be granted at this time, then `None` is returned.
894    /// Otherwise, an RAII guard is returned which will release the shared access
895    /// when it is dropped.
896    ///
897    /// This method is guaranteed to succeed if another read lock is held at the
898    /// time of the call. See the documentation for `read_recursive` for details.
899    ///
900    /// This function does not block.
901    #[inline]
902    pub fn try_read_recursive(&self) -> Option<RwLockReadGuard<'_, R, T>> {
903        if self.raw.try_lock_shared_recursive() {
904            // SAFETY: The lock is held, as required.
905            Some(unsafe { self.make_read_guard_unchecked() })
906        } else {
907            None
908        }
909    }
910
911    /// Locks this `RwLock` with shared read access, through an `Arc`.
912    ///
913    /// This method is similar to the `read_recursive` method; however, it requires the `RwLock` to be inside of
914    /// an `Arc` and the resulting read guard has no lifetime requirements.
915    #[cfg(feature = "arc_lock")]
916    #[inline]
917    pub fn read_arc_recursive(self: &Arc<Self>) -> ArcRwLockReadGuard<R, T> {
918        self.raw.lock_shared_recursive();
919        // SAFETY: locking guarantee is upheld
920        unsafe { self.make_arc_read_guard_unchecked() }
921    }
922
923    /// Attempts to lock this `RwLock` with shared read access, through an `Arc`.
924    ///
925    /// This method is similar to the `try_read_recursive` method; however, it requires the `RwLock` to be inside
926    /// of an `Arc` and the resulting read guard has no lifetime requirements.
927    #[cfg(feature = "arc_lock")]
928    #[inline]
929    pub fn try_read_recursive_arc(self: &Arc<Self>) -> Option<ArcRwLockReadGuard<R, T>> {
930        if self.raw.try_lock_shared_recursive() {
931            // SAFETY: locking guarantee is upheld
932            Some(unsafe { self.make_arc_read_guard_unchecked() })
933        } else {
934            None
935        }
936    }
937}
938
939impl<R: RawRwLockRecursiveTimed, T: ?Sized> RwLock<R, T> {
940    /// Attempts to acquire this `RwLock` with shared read access until a timeout
941    /// is reached.
942    ///
943    /// If the access could not be granted before the timeout expires, then
944    /// `None` is returned. Otherwise, an RAII guard is returned which will
945    /// release the shared access when it is dropped.
946    ///
947    /// This method is guaranteed to succeed without blocking if another read
948    /// lock is held at the time of the call. See the documentation for
949    /// `read_recursive` for details.
950    #[inline]
951    pub fn try_read_recursive_for(
952        &self,
953        timeout: R::Duration,
954    ) -> Option<RwLockReadGuard<'_, R, T>> {
955        if self.raw.try_lock_shared_recursive_for(timeout) {
956            // SAFETY: The lock is held, as required.
957            Some(unsafe { self.make_read_guard_unchecked() })
958        } else {
959            None
960        }
961    }
962
963    /// Attempts to acquire this `RwLock` with shared read access until a timeout
964    /// is reached.
965    ///
966    /// If the access could not be granted before the timeout expires, then
967    /// `None` is returned. Otherwise, an RAII guard is returned which will
968    /// release the shared access when it is dropped.
969    #[inline]
970    pub fn try_read_recursive_until(
971        &self,
972        timeout: R::Instant,
973    ) -> Option<RwLockReadGuard<'_, R, T>> {
974        if self.raw.try_lock_shared_recursive_until(timeout) {
975            // SAFETY: The lock is held, as required.
976            Some(unsafe { self.make_read_guard_unchecked() })
977        } else {
978            None
979        }
980    }
981
982    /// Attempts to lock this `RwLock` with read access until a timeout is reached, through an `Arc`.
983    ///
984    /// This method is similar to the `try_read_recursive_for` method; however, it requires the `RwLock` to be
985    /// inside of an `Arc` and the resulting read guard has no lifetime requirements.
986    #[cfg(feature = "arc_lock")]
987    #[inline]
988    pub fn try_read_arc_recursive_for(
989        self: &Arc<Self>,
990        timeout: R::Duration,
991    ) -> Option<ArcRwLockReadGuard<R, T>> {
992        if self.raw.try_lock_shared_recursive_for(timeout) {
993            // SAFETY: locking guarantee is upheld
994            Some(unsafe { self.make_arc_read_guard_unchecked() })
995        } else {
996            None
997        }
998    }
999
1000    /// Attempts to lock this `RwLock` with read access until a timeout is reached, through an `Arc`.
1001    ///
1002    /// This method is similar to the `try_read_recursive_until` method; however, it requires the `RwLock` to be
1003    /// inside of an `Arc` and the resulting read guard has no lifetime requirements.
1004    #[cfg(feature = "arc_lock")]
1005    #[inline]
1006    pub fn try_read_arc_recursive_until(
1007        self: &Arc<Self>,
1008        timeout: R::Instant,
1009    ) -> Option<ArcRwLockReadGuard<R, T>> {
1010        if self.raw.try_lock_shared_recursive_until(timeout) {
1011            // SAFETY: locking guarantee is upheld
1012            Some(unsafe { self.make_arc_read_guard_unchecked() })
1013        } else {
1014            None
1015        }
1016    }
1017}
1018
1019impl<R: RawRwLockUpgrade, T: ?Sized> RwLock<R, T> {
1020    /// Creates a new `RwLockUpgradableReadGuard` without checking if the lock is held.
1021    ///
1022    /// # Safety
1023    ///
1024    /// This method must only be called if the thread logically holds an upgradable read lock.
1025    ///
1026    /// This function does not increment the read count of the lock. Calling this function when a
1027    /// guard has already been produced is undefined behaviour unless the guard was forgotten
1028    /// with `mem::forget`.
1029    #[inline]
1030    pub unsafe fn make_upgradable_guard_unchecked(&self) -> RwLockUpgradableReadGuard<'_, R, T> {
1031        RwLockUpgradableReadGuard {
1032            rwlock: self,
1033            marker: PhantomData,
1034        }
1035    }
1036
1037    /// Locks this `RwLock` with upgradable read access, blocking the current thread
1038    /// until it can be acquired.
1039    ///
1040    /// The calling thread will be blocked until there are no more writers or other
1041    /// upgradable reads which hold the lock. There may be other readers currently
1042    /// inside the lock when this method returns.
1043    ///
1044    /// Returns an RAII guard which will release this thread's shared access
1045    /// once it is dropped.
1046    #[inline]
1047    pub fn upgradable_read(&self) -> RwLockUpgradableReadGuard<'_, R, T> {
1048        self.raw.lock_upgradable();
1049        // SAFETY: The lock is held, as required.
1050        unsafe { self.make_upgradable_guard_unchecked() }
1051    }
1052
1053    /// Attempts to acquire this `RwLock` with upgradable read access.
1054    ///
1055    /// If the access could not be granted at this time, then `None` is returned.
1056    /// Otherwise, an RAII guard is returned which will release the shared access
1057    /// when it is dropped.
1058    ///
1059    /// This function does not block.
1060    #[inline]
1061    pub fn try_upgradable_read(&self) -> Option<RwLockUpgradableReadGuard<'_, R, T>> {
1062        if self.raw.try_lock_upgradable() {
1063            // SAFETY: The lock is held, as required.
1064            Some(unsafe { self.make_upgradable_guard_unchecked() })
1065        } else {
1066            None
1067        }
1068    }
1069
1070    /// Creates a new `ArcRwLockUpgradableReadGuard` without checking if the lock is held.
1071    ///
1072    /// # Safety
1073    ///
1074    /// This method must only be called if the thread logically holds an upgradable read lock.
1075    ///
1076    /// This function does not increment the read count of the lock. Calling this function when a
1077    /// guard has already been produced is undefined behaviour unless the guard was forgotten
1078    /// with `mem::forget`.`
1079    #[cfg(feature = "arc_lock")]
1080    #[inline]
1081    pub unsafe fn make_upgradable_arc_guard_unchecked(
1082        self: &Arc<Self>,
1083    ) -> ArcRwLockUpgradableReadGuard<R, T> {
1084        ArcRwLockUpgradableReadGuard {
1085            rwlock: self.clone(),
1086            marker: PhantomData,
1087        }
1088    }
1089
1090    /// Locks this `RwLock` with upgradable read access, through an `Arc`.
1091    ///
1092    /// This method is similar to the `upgradable_read` method; however, it requires the `RwLock` to be
1093    /// inside of an `Arc` and the resulting read guard has no lifetime requirements.
1094    #[cfg(feature = "arc_lock")]
1095    #[inline]
1096    pub fn upgradable_read_arc(self: &Arc<Self>) -> ArcRwLockUpgradableReadGuard<R, T> {
1097        self.raw.lock_upgradable();
1098        // SAFETY: locking guarantee is upheld
1099        unsafe { self.make_upgradable_arc_guard_unchecked() }
1100    }
1101
1102    /// Attempts to lock this `RwLock` with upgradable read access, through an `Arc`.
1103    ///
1104    /// This method is similar to the `try_upgradable_read` method; however, it requires the `RwLock` to be
1105    /// inside of an `Arc` and the resulting read guard has no lifetime requirements.
1106    #[cfg(feature = "arc_lock")]
1107    #[inline]
1108    pub fn try_upgradable_read_arc(self: &Arc<Self>) -> Option<ArcRwLockUpgradableReadGuard<R, T>> {
1109        if self.raw.try_lock_upgradable() {
1110            // SAFETY: locking guarantee is upheld
1111            Some(unsafe { self.make_upgradable_arc_guard_unchecked() })
1112        } else {
1113            None
1114        }
1115    }
1116}
1117
1118impl<R: RawRwLockUpgradeTimed, T: ?Sized> RwLock<R, T> {
1119    /// Attempts to acquire this `RwLock` with upgradable read access until a timeout
1120    /// is reached.
1121    ///
1122    /// If the access could not be granted before the timeout expires, then
1123    /// `None` is returned. Otherwise, an RAII guard is returned which will
1124    /// release the shared access when it is dropped.
1125    #[inline]
1126    pub fn try_upgradable_read_for(
1127        &self,
1128        timeout: R::Duration,
1129    ) -> Option<RwLockUpgradableReadGuard<'_, R, T>> {
1130        if self.raw.try_lock_upgradable_for(timeout) {
1131            // SAFETY: The lock is held, as required.
1132            Some(unsafe { self.make_upgradable_guard_unchecked() })
1133        } else {
1134            None
1135        }
1136    }
1137
1138    /// Attempts to acquire this `RwLock` with upgradable read access until a timeout
1139    /// is reached.
1140    ///
1141    /// If the access could not be granted before the timeout expires, then
1142    /// `None` is returned. Otherwise, an RAII guard is returned which will
1143    /// release the shared access when it is dropped.
1144    #[inline]
1145    pub fn try_upgradable_read_until(
1146        &self,
1147        timeout: R::Instant,
1148    ) -> Option<RwLockUpgradableReadGuard<'_, R, T>> {
1149        if self.raw.try_lock_upgradable_until(timeout) {
1150            // SAFETY: The lock is held, as required.
1151            Some(unsafe { self.make_upgradable_guard_unchecked() })
1152        } else {
1153            None
1154        }
1155    }
1156
1157    /// Attempts to lock this `RwLock` with upgradable access until a timeout is reached, through an `Arc`.
1158    ///
1159    /// This method is similar to the `try_upgradable_read_for` method; however, it requires the `RwLock` to be
1160    /// inside of an `Arc` and the resulting read guard has no lifetime requirements.
1161    #[cfg(feature = "arc_lock")]
1162    #[inline]
1163    pub fn try_upgradable_read_arc_for(
1164        self: &Arc<Self>,
1165        timeout: R::Duration,
1166    ) -> Option<ArcRwLockUpgradableReadGuard<R, T>> {
1167        if self.raw.try_lock_upgradable_for(timeout) {
1168            // SAFETY: locking guarantee is upheld
1169            Some(unsafe { self.make_upgradable_arc_guard_unchecked() })
1170        } else {
1171            None
1172        }
1173    }
1174
1175    /// Attempts to lock this `RwLock` with upgradable access until a timeout is reached, through an `Arc`.
1176    ///
1177    /// This method is similar to the `try_upgradable_read_until` method; however, it requires the `RwLock` to be
1178    /// inside of an `Arc` and the resulting read guard has no lifetime requirements.
1179    #[cfg(feature = "arc_lock")]
1180    #[inline]
1181    pub fn try_upgradable_read_arc_until(
1182        self: &Arc<Self>,
1183        timeout: R::Instant,
1184    ) -> Option<ArcRwLockUpgradableReadGuard<R, T>> {
1185        if self.raw.try_lock_upgradable_until(timeout) {
1186            // SAFETY: locking guarantee is upheld
1187            Some(unsafe { self.make_upgradable_arc_guard_unchecked() })
1188        } else {
1189            None
1190        }
1191    }
1192}
1193
1194impl<R: RawRwLock, T: ?Sized + Default> Default for RwLock<R, T> {
1195    #[inline]
1196    fn default() -> RwLock<R, T> {
1197        RwLock::new(Default::default())
1198    }
1199}
1200
1201impl<R: RawRwLock, T> From<T> for RwLock<R, T> {
1202    #[inline]
1203    fn from(t: T) -> RwLock<R, T> {
1204        RwLock::new(t)
1205    }
1206}
1207
1208impl<R: RawRwLock, T: ?Sized + fmt::Debug> fmt::Debug for RwLock<R, T> {
1209    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1210        let mut d = f.debug_struct("RwLock");
1211        match self.try_read() {
1212            Some(guard) => d.field("data", &&*guard),
1213            None => {
1214                // Additional format_args! here is to remove quotes around <locked> in debug output.
1215                d.field("data", &format_args!("<locked>"))
1216            }
1217        };
1218        d.finish()
1219    }
1220}
1221
1222/// RAII structure used to release the shared read access of a lock when
1223/// dropped.
1224#[clippy::has_significant_drop]
1225#[must_use = "if unused the RwLock will immediately unlock"]
1226pub struct RwLockReadGuard<'a, R: RawRwLock, T: ?Sized> {
1227    rwlock: &'a RwLock<R, T>,
1228    marker: PhantomData<(&'a T, R::GuardMarker)>,
1229}
1230
1231unsafe impl<R: RawRwLock + Sync, T: Sync + ?Sized> Sync for RwLockReadGuard<'_, R, T> {}
1232
1233impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> RwLockReadGuard<'a, R, T> {
1234    /// Returns a reference to the original reader-writer lock object.
1235    pub fn rwlock(s: &Self) -> &'a RwLock<R, T> {
1236        s.rwlock
1237    }
1238
1239    /// Make a new `MappedRwLockReadGuard` for a component of the locked data.
1240    ///
1241    /// This operation cannot fail as the `RwLockReadGuard` passed
1242    /// in already locked the data.
1243    ///
1244    /// This is an associated function that needs to be
1245    /// used as `RwLockReadGuard::map(...)`. A method would interfere with methods of
1246    /// the same name on the contents of the locked data.
1247    #[inline]
1248    pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedRwLockReadGuard<'a, R, U>
1249    where
1250        F: FnOnce(&T) -> &U,
1251    {
1252        let raw = &s.rwlock.raw;
1253        let data = f(unsafe { &*s.rwlock.data.get() });
1254        mem::forget(s);
1255        MappedRwLockReadGuard {
1256            raw,
1257            data,
1258            marker: PhantomData,
1259        }
1260    }
1261
1262    /// Attempts to make  a new `MappedRwLockReadGuard` for a component of the
1263    /// locked data. Returns the original guard if the closure returns `None`.
1264    ///
1265    /// This operation cannot fail as the `RwLockReadGuard` passed
1266    /// in already locked the data.
1267    ///
1268    /// This is an associated function that needs to be
1269    /// used as `RwLockReadGuard::try_map(...)`. A method would interfere with methods of
1270    /// the same name on the contents of the locked data.
1271    #[inline]
1272    pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockReadGuard<'a, R, U>, Self>
1273    where
1274        F: FnOnce(&T) -> Option<&U>,
1275    {
1276        let raw = &s.rwlock.raw;
1277        let data = match f(unsafe { &*s.rwlock.data.get() }) {
1278            Some(data) => data,
1279            None => return Err(s),
1280        };
1281        mem::forget(s);
1282        Ok(MappedRwLockReadGuard {
1283            raw,
1284            data,
1285            marker: PhantomData,
1286        })
1287    }
1288
1289    /// Temporarily unlocks the `RwLock` to execute the given function.
1290    ///
1291    /// This is safe because `&mut` guarantees that there exist no other
1292    /// references to the data protected by the `RwLock`.
1293    #[inline]
1294    pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
1295    where
1296        F: FnOnce() -> U,
1297    {
1298        // Safety: An RwLockReadGuard always holds a shared lock.
1299        unsafe {
1300            s.rwlock.raw.unlock_shared();
1301        }
1302        defer!(s.rwlock.raw.lock_shared());
1303        f()
1304    }
1305}
1306
1307impl<'a, R: RawRwLockFair + 'a, T: ?Sized + 'a> RwLockReadGuard<'a, R, T> {
1308    /// Unlocks the `RwLock` using a fair unlock protocol.
1309    ///
1310    /// By default, `RwLock` is unfair and allow the current thread to re-lock
1311    /// the `RwLock` before another has the chance to acquire the lock, even if
1312    /// that thread has been blocked on the `RwLock` for a long time. This is
1313    /// the default because it allows much higher throughput as it avoids
1314    /// forcing a context switch on every `RwLock` unlock. This can result in one
1315    /// thread acquiring a `RwLock` many more times than other threads.
1316    ///
1317    /// However in some cases it can be beneficial to ensure fairness by forcing
1318    /// the lock to pass on to a waiting thread if there is one. This is done by
1319    /// using this method instead of dropping the `RwLockReadGuard` normally.
1320    #[inline]
1321    pub fn unlock_fair(s: Self) {
1322        // Safety: An RwLockReadGuard always holds a shared lock.
1323        unsafe {
1324            s.rwlock.raw.unlock_shared_fair();
1325        }
1326        mem::forget(s);
1327    }
1328
1329    /// Temporarily unlocks the `RwLock` to execute the given function.
1330    ///
1331    /// The `RwLock` is unlocked a fair unlock protocol.
1332    ///
1333    /// This is safe because `&mut` guarantees that there exist no other
1334    /// references to the data protected by the `RwLock`.
1335    #[inline]
1336    pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
1337    where
1338        F: FnOnce() -> U,
1339    {
1340        // Safety: An RwLockReadGuard always holds a shared lock.
1341        unsafe {
1342            s.rwlock.raw.unlock_shared_fair();
1343        }
1344        defer!(s.rwlock.raw.lock_shared());
1345        f()
1346    }
1347
1348    /// Temporarily yields the `RwLock` to a waiting thread if there is one.
1349    ///
1350    /// This method is functionally equivalent to calling `unlock_fair` followed
1351    /// by `read`, however it can be much more efficient in the case where there
1352    /// are no waiting threads.
1353    #[inline]
1354    pub fn bump(s: &mut Self) {
1355        // Safety: An RwLockReadGuard always holds a shared lock.
1356        unsafe {
1357            s.rwlock.raw.bump_shared();
1358        }
1359    }
1360}
1361
1362impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Deref for RwLockReadGuard<'a, R, T> {
1363    type Target = T;
1364    #[inline]
1365    fn deref(&self) -> &T {
1366        unsafe { &*self.rwlock.data.get() }
1367    }
1368}
1369
1370impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for RwLockReadGuard<'a, R, T> {
1371    #[inline]
1372    fn drop(&mut self) {
1373        // Safety: An RwLockReadGuard always holds a shared lock.
1374        unsafe {
1375            self.rwlock.raw.unlock_shared();
1376        }
1377    }
1378}
1379
1380impl<'a, R: RawRwLock + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for RwLockReadGuard<'a, R, T> {
1381    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1382        fmt::Debug::fmt(&**self, f)
1383    }
1384}
1385
1386impl<'a, R: RawRwLock + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display
1387    for RwLockReadGuard<'a, R, T>
1388{
1389    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1390        (**self).fmt(f)
1391    }
1392}
1393
1394#[cfg(feature = "owning_ref")]
1395unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> StableAddress for RwLockReadGuard<'a, R, T> {}
1396
1397/// An RAII rwlock guard returned by the `Arc` locking operations on `RwLock`.
1398///
1399/// This is similar to the `RwLockReadGuard` struct, except instead of using a reference to unlock the `RwLock`
1400/// it uses an `Arc<RwLock>`. This has several advantages, most notably that it has an `'static` lifetime.
1401#[cfg(feature = "arc_lock")]
1402#[clippy::has_significant_drop]
1403#[must_use = "if unused the RwLock will immediately unlock"]
1404pub struct ArcRwLockReadGuard<R: RawRwLock, T: ?Sized> {
1405    rwlock: Arc<RwLock<R, T>>,
1406    marker: PhantomData<R::GuardMarker>,
1407}
1408
1409#[cfg(feature = "arc_lock")]
1410impl<R: RawRwLock, T: ?Sized> ArcRwLockReadGuard<R, T> {
1411    /// Returns a reference to the rwlock, contained in its `Arc`.
1412    pub fn rwlock(s: &Self) -> &Arc<RwLock<R, T>> {
1413        &s.rwlock
1414    }
1415
1416    /// Temporarily unlocks the `RwLock` to execute the given function.
1417    ///
1418    /// This is functionally identical to the `unlocked` method on [`RwLockReadGuard`].
1419    #[inline]
1420    pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
1421    where
1422        F: FnOnce() -> U,
1423    {
1424        // Safety: An RwLockReadGuard always holds a shared lock.
1425        unsafe {
1426            s.rwlock.raw.unlock_shared();
1427        }
1428        defer!(s.rwlock.raw.lock_shared());
1429        f()
1430    }
1431}
1432
1433#[cfg(feature = "arc_lock")]
1434impl<R: RawRwLockFair, T: ?Sized> ArcRwLockReadGuard<R, T> {
1435    /// Unlocks the `RwLock` using a fair unlock protocol.
1436    ///
1437    /// This is functionally identical to the `unlock_fair` method on [`RwLockReadGuard`].
1438    #[inline]
1439    pub fn unlock_fair(s: Self) {
1440        // Safety: An RwLockReadGuard always holds a shared lock.
1441        unsafe {
1442            s.rwlock.raw.unlock_shared_fair();
1443        }
1444
1445        // SAFETY: ensure the Arc has its refcount decremented
1446        let mut s = ManuallyDrop::new(s);
1447        unsafe { ptr::drop_in_place(&mut s.rwlock) };
1448    }
1449
1450    /// Temporarily unlocks the `RwLock` to execute the given function.
1451    ///
1452    /// This is functionally identical to the `unlocked_fair` method on [`RwLockReadGuard`].
1453    #[inline]
1454    pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
1455    where
1456        F: FnOnce() -> U,
1457    {
1458        // Safety: An RwLockReadGuard always holds a shared lock.
1459        unsafe {
1460            s.rwlock.raw.unlock_shared_fair();
1461        }
1462        defer!(s.rwlock.raw.lock_shared());
1463        f()
1464    }
1465
1466    /// Temporarily yields the `RwLock` to a waiting thread if there is one.
1467    ///
1468    /// This is functionally identical to the `bump` method on [`RwLockReadGuard`].
1469    #[inline]
1470    pub fn bump(s: &mut Self) {
1471        // Safety: An RwLockReadGuard always holds a shared lock.
1472        unsafe {
1473            s.rwlock.raw.bump_shared();
1474        }
1475    }
1476}
1477
1478#[cfg(feature = "arc_lock")]
1479impl<R: RawRwLock, T: ?Sized> Deref for ArcRwLockReadGuard<R, T> {
1480    type Target = T;
1481    #[inline]
1482    fn deref(&self) -> &T {
1483        unsafe { &*self.rwlock.data.get() }
1484    }
1485}
1486
1487#[cfg(feature = "arc_lock")]
1488impl<R: RawRwLock, T: ?Sized> Drop for ArcRwLockReadGuard<R, T> {
1489    #[inline]
1490    fn drop(&mut self) {
1491        // Safety: An RwLockReadGuard always holds a shared lock.
1492        unsafe {
1493            self.rwlock.raw.unlock_shared();
1494        }
1495    }
1496}
1497
1498#[cfg(feature = "arc_lock")]
1499impl<R: RawRwLock, T: fmt::Debug + ?Sized> fmt::Debug for ArcRwLockReadGuard<R, T> {
1500    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1501        fmt::Debug::fmt(&**self, f)
1502    }
1503}
1504
1505#[cfg(feature = "arc_lock")]
1506impl<R: RawRwLock, T: fmt::Display + ?Sized> fmt::Display for ArcRwLockReadGuard<R, T> {
1507    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1508        (**self).fmt(f)
1509    }
1510}
1511
1512/// RAII structure used to release the exclusive write access of a lock when
1513/// dropped.
1514#[clippy::has_significant_drop]
1515#[must_use = "if unused the RwLock will immediately unlock"]
1516pub struct RwLockWriteGuard<'a, R: RawRwLock, T: ?Sized> {
1517    rwlock: &'a RwLock<R, T>,
1518    marker: PhantomData<(&'a mut T, R::GuardMarker)>,
1519}
1520
1521unsafe impl<R: RawRwLock + Sync, T: Sync + ?Sized> Sync for RwLockWriteGuard<'_, R, T> {}
1522
1523impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> RwLockWriteGuard<'a, R, T> {
1524    /// Returns a reference to the original reader-writer lock object.
1525    pub fn rwlock(s: &Self) -> &'a RwLock<R, T> {
1526        s.rwlock
1527    }
1528
1529    /// Make a new `MappedRwLockWriteGuard` for a component of the locked data.
1530    ///
1531    /// This operation cannot fail as the `RwLockWriteGuard` passed
1532    /// in already locked the data.
1533    ///
1534    /// This is an associated function that needs to be
1535    /// used as `RwLockWriteGuard::map(...)`. A method would interfere with methods of
1536    /// the same name on the contents of the locked data.
1537    #[inline]
1538    pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedRwLockWriteGuard<'a, R, U>
1539    where
1540        F: FnOnce(&mut T) -> &mut U,
1541    {
1542        let raw = &s.rwlock.raw;
1543        let data = f(unsafe { &mut *s.rwlock.data.get() });
1544        mem::forget(s);
1545        MappedRwLockWriteGuard {
1546            raw,
1547            data,
1548            marker: PhantomData,
1549        }
1550    }
1551
1552    /// Attempts to make  a new `MappedRwLockWriteGuard` for a component of the
1553    /// locked data. The original guard is return if the closure returns `None`.
1554    ///
1555    /// This operation cannot fail as the `RwLockWriteGuard` passed
1556    /// in already locked the data.
1557    ///
1558    /// This is an associated function that needs to be
1559    /// used as `RwLockWriteGuard::try_map(...)`. A method would interfere with methods of
1560    /// the same name on the contents of the locked data.
1561    #[inline]
1562    pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, R, U>, Self>
1563    where
1564        F: FnOnce(&mut T) -> Option<&mut U>,
1565    {
1566        let raw = &s.rwlock.raw;
1567        let data = match f(unsafe { &mut *s.rwlock.data.get() }) {
1568            Some(data) => data,
1569            None => return Err(s),
1570        };
1571        mem::forget(s);
1572        Ok(MappedRwLockWriteGuard {
1573            raw,
1574            data,
1575            marker: PhantomData,
1576        })
1577    }
1578
1579    /// Temporarily unlocks the `RwLock` to execute the given function.
1580    ///
1581    /// This is safe because `&mut` guarantees that there exist no other
1582    /// references to the data protected by the `RwLock`.
1583    #[inline]
1584    pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
1585    where
1586        F: FnOnce() -> U,
1587    {
1588        // Safety: An RwLockReadGuard always holds a shared lock.
1589        unsafe {
1590            s.rwlock.raw.unlock_exclusive();
1591        }
1592        defer!(s.rwlock.raw.lock_exclusive());
1593        f()
1594    }
1595}
1596
1597impl<'a, R: RawRwLockDowngrade + 'a, T: ?Sized + 'a> RwLockWriteGuard<'a, R, T> {
1598    /// Atomically downgrades a write lock into a read lock without allowing any
1599    /// writers to take exclusive access of the lock in the meantime.
1600    ///
1601    /// Note that if there are any writers currently waiting to take the lock
1602    /// then other readers may not be able to acquire the lock even if it was
1603    /// downgraded.
1604    pub fn downgrade(s: Self) -> RwLockReadGuard<'a, R, T> {
1605        // Safety: An RwLockWriteGuard always holds an exclusive lock.
1606        unsafe {
1607            s.rwlock.raw.downgrade();
1608        }
1609        let rwlock = s.rwlock;
1610        mem::forget(s);
1611        RwLockReadGuard {
1612            rwlock,
1613            marker: PhantomData,
1614        }
1615    }
1616}
1617
1618impl<'a, R: RawRwLockUpgradeDowngrade + 'a, T: ?Sized + 'a> RwLockWriteGuard<'a, R, T> {
1619    /// Atomically downgrades a write lock into an upgradable read lock without allowing any
1620    /// writers to take exclusive access of the lock in the meantime.
1621    ///
1622    /// Note that if there are any writers currently waiting to take the lock
1623    /// then other readers may not be able to acquire the lock even if it was
1624    /// downgraded.
1625    pub fn downgrade_to_upgradable(s: Self) -> RwLockUpgradableReadGuard<'a, R, T> {
1626        // Safety: An RwLockWriteGuard always holds an exclusive lock.
1627        unsafe {
1628            s.rwlock.raw.downgrade_to_upgradable();
1629        }
1630        let rwlock = s.rwlock;
1631        mem::forget(s);
1632        RwLockUpgradableReadGuard {
1633            rwlock,
1634            marker: PhantomData,
1635        }
1636    }
1637}
1638
1639impl<'a, R: RawRwLockFair + 'a, T: ?Sized + 'a> RwLockWriteGuard<'a, R, T> {
1640    /// Unlocks the `RwLock` using a fair unlock protocol.
1641    ///
1642    /// By default, `RwLock` is unfair and allow the current thread to re-lock
1643    /// the `RwLock` before another has the chance to acquire the lock, even if
1644    /// that thread has been blocked on the `RwLock` for a long time. This is
1645    /// the default because it allows much higher throughput as it avoids
1646    /// forcing a context switch on every `RwLock` unlock. This can result in one
1647    /// thread acquiring a `RwLock` many more times than other threads.
1648    ///
1649    /// However in some cases it can be beneficial to ensure fairness by forcing
1650    /// the lock to pass on to a waiting thread if there is one. This is done by
1651    /// using this method instead of dropping the `RwLockWriteGuard` normally.
1652    #[inline]
1653    pub fn unlock_fair(s: Self) {
1654        // Safety: An RwLockWriteGuard always holds an exclusive lock.
1655        unsafe {
1656            s.rwlock.raw.unlock_exclusive_fair();
1657        }
1658        mem::forget(s);
1659    }
1660
1661    /// Temporarily unlocks the `RwLock` to execute the given function.
1662    ///
1663    /// The `RwLock` is unlocked a fair unlock protocol.
1664    ///
1665    /// This is safe because `&mut` guarantees that there exist no other
1666    /// references to the data protected by the `RwLock`.
1667    #[inline]
1668    pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
1669    where
1670        F: FnOnce() -> U,
1671    {
1672        // Safety: An RwLockWriteGuard always holds an exclusive lock.
1673        unsafe {
1674            s.rwlock.raw.unlock_exclusive_fair();
1675        }
1676        defer!(s.rwlock.raw.lock_exclusive());
1677        f()
1678    }
1679
1680    /// Temporarily yields the `RwLock` to a waiting thread if there is one.
1681    ///
1682    /// This method is functionally equivalent to calling `unlock_fair` followed
1683    /// by `write`, however it can be much more efficient in the case where there
1684    /// are no waiting threads.
1685    #[inline]
1686    pub fn bump(s: &mut Self) {
1687        // Safety: An RwLockWriteGuard always holds an exclusive lock.
1688        unsafe {
1689            s.rwlock.raw.bump_exclusive();
1690        }
1691    }
1692}
1693
1694impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Deref for RwLockWriteGuard<'a, R, T> {
1695    type Target = T;
1696    #[inline]
1697    fn deref(&self) -> &T {
1698        unsafe { &*self.rwlock.data.get() }
1699    }
1700}
1701
1702impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> DerefMut for RwLockWriteGuard<'a, R, T> {
1703    #[inline]
1704    fn deref_mut(&mut self) -> &mut T {
1705        unsafe { &mut *self.rwlock.data.get() }
1706    }
1707}
1708
1709impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for RwLockWriteGuard<'a, R, T> {
1710    #[inline]
1711    fn drop(&mut self) {
1712        // Safety: An RwLockWriteGuard always holds an exclusive lock.
1713        unsafe {
1714            self.rwlock.raw.unlock_exclusive();
1715        }
1716    }
1717}
1718
1719impl<'a, R: RawRwLock + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for RwLockWriteGuard<'a, R, T> {
1720    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1721        fmt::Debug::fmt(&**self, f)
1722    }
1723}
1724
1725impl<'a, R: RawRwLock + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display
1726    for RwLockWriteGuard<'a, R, T>
1727{
1728    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1729        (**self).fmt(f)
1730    }
1731}
1732
1733#[cfg(feature = "owning_ref")]
1734unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> StableAddress for RwLockWriteGuard<'a, R, T> {}
1735
1736/// An RAII rwlock guard returned by the `Arc` locking operations on `RwLock`.
1737/// This is similar to the `RwLockWriteGuard` struct, except instead of using a reference to unlock the `RwLock`
1738/// it uses an `Arc<RwLock>`. This has several advantages, most notably that it has an `'static` lifetime.
1739#[cfg(feature = "arc_lock")]
1740#[clippy::has_significant_drop]
1741#[must_use = "if unused the RwLock will immediately unlock"]
1742pub struct ArcRwLockWriteGuard<R: RawRwLock, T: ?Sized> {
1743    rwlock: Arc<RwLock<R, T>>,
1744    marker: PhantomData<R::GuardMarker>,
1745}
1746
1747#[cfg(feature = "arc_lock")]
1748impl<R: RawRwLock, T: ?Sized> ArcRwLockWriteGuard<R, T> {
1749    /// Returns a reference to the rwlock, contained in its `Arc`.
1750    pub fn rwlock(s: &Self) -> &Arc<RwLock<R, T>> {
1751        &s.rwlock
1752    }
1753
1754    /// Temporarily unlocks the `RwLock` to execute the given function.
1755    ///
1756    /// This is functionally equivalent to the `unlocked` method on [`RwLockWriteGuard`].
1757    #[inline]
1758    pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
1759    where
1760        F: FnOnce() -> U,
1761    {
1762        // Safety: An RwLockWriteGuard always holds a shared lock.
1763        unsafe {
1764            s.rwlock.raw.unlock_exclusive();
1765        }
1766        defer!(s.rwlock.raw.lock_exclusive());
1767        f()
1768    }
1769}
1770
1771#[cfg(feature = "arc_lock")]
1772impl<R: RawRwLockDowngrade, T: ?Sized> ArcRwLockWriteGuard<R, T> {
1773    /// Atomically downgrades a write lock into a read lock without allowing any
1774    /// writers to take exclusive access of the lock in the meantime.
1775    ///
1776    /// This is functionally equivalent to the `downgrade` method on [`RwLockWriteGuard`].
1777    pub fn downgrade(s: Self) -> ArcRwLockReadGuard<R, T> {
1778        // Safety: An RwLockWriteGuard always holds an exclusive lock.
1779        unsafe {
1780            s.rwlock.raw.downgrade();
1781        }
1782
1783        // SAFETY: prevent the arc's refcount from changing using ManuallyDrop and ptr::read
1784        let s = ManuallyDrop::new(s);
1785        let rwlock = unsafe { ptr::read(&s.rwlock) };
1786
1787        ArcRwLockReadGuard {
1788            rwlock,
1789            marker: PhantomData,
1790        }
1791    }
1792}
1793
1794#[cfg(feature = "arc_lock")]
1795impl<R: RawRwLockUpgradeDowngrade, T: ?Sized> ArcRwLockWriteGuard<R, T> {
1796    /// Atomically downgrades a write lock into an upgradable read lock without allowing any
1797    /// writers to take exclusive access of the lock in the meantime.
1798    ///
1799    /// This is functionally identical to the `downgrade_to_upgradable` method on [`RwLockWriteGuard`].
1800    pub fn downgrade_to_upgradable(s: Self) -> ArcRwLockUpgradableReadGuard<R, T> {
1801        // Safety: An RwLockWriteGuard always holds an exclusive lock.
1802        unsafe {
1803            s.rwlock.raw.downgrade_to_upgradable();
1804        }
1805
1806        // SAFETY: same as above
1807        let s = ManuallyDrop::new(s);
1808        let rwlock = unsafe { ptr::read(&s.rwlock) };
1809
1810        ArcRwLockUpgradableReadGuard {
1811            rwlock,
1812            marker: PhantomData,
1813        }
1814    }
1815}
1816
1817#[cfg(feature = "arc_lock")]
1818impl<R: RawRwLockFair, T: ?Sized> ArcRwLockWriteGuard<R, T> {
1819    /// Unlocks the `RwLock` using a fair unlock protocol.
1820    ///
1821    /// This is functionally equivalent to the `unlock_fair` method on [`RwLockWriteGuard`].
1822    #[inline]
1823    pub fn unlock_fair(s: Self) {
1824        // Safety: An RwLockWriteGuard always holds an exclusive lock.
1825        unsafe {
1826            s.rwlock.raw.unlock_exclusive_fair();
1827        }
1828
1829        // SAFETY: prevent the Arc from leaking memory
1830        let mut s = ManuallyDrop::new(s);
1831        unsafe { ptr::drop_in_place(&mut s.rwlock) };
1832    }
1833
1834    /// Temporarily unlocks the `RwLock` to execute the given function.
1835    ///
1836    /// This is functionally equivalent to the `unlocked_fair` method on [`RwLockWriteGuard`].
1837    #[inline]
1838    pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
1839    where
1840        F: FnOnce() -> U,
1841    {
1842        // Safety: An RwLockWriteGuard always holds an exclusive lock.
1843        unsafe {
1844            s.rwlock.raw.unlock_exclusive_fair();
1845        }
1846        defer!(s.rwlock.raw.lock_exclusive());
1847        f()
1848    }
1849
1850    /// Temporarily yields the `RwLock` to a waiting thread if there is one.
1851    ///
1852    /// This method is functionally equivalent to the `bump` method on [`RwLockWriteGuard`].
1853    #[inline]
1854    pub fn bump(s: &mut Self) {
1855        // Safety: An RwLockWriteGuard always holds an exclusive lock.
1856        unsafe {
1857            s.rwlock.raw.bump_exclusive();
1858        }
1859    }
1860}
1861
1862#[cfg(feature = "arc_lock")]
1863impl<R: RawRwLock, T: ?Sized> Deref for ArcRwLockWriteGuard<R, T> {
1864    type Target = T;
1865    #[inline]
1866    fn deref(&self) -> &T {
1867        unsafe { &*self.rwlock.data.get() }
1868    }
1869}
1870
1871#[cfg(feature = "arc_lock")]
1872impl<R: RawRwLock, T: ?Sized> DerefMut for ArcRwLockWriteGuard<R, T> {
1873    #[inline]
1874    fn deref_mut(&mut self) -> &mut T {
1875        unsafe { &mut *self.rwlock.data.get() }
1876    }
1877}
1878
1879#[cfg(feature = "arc_lock")]
1880impl<R: RawRwLock, T: ?Sized> Drop for ArcRwLockWriteGuard<R, T> {
1881    #[inline]
1882    fn drop(&mut self) {
1883        // Safety: An RwLockWriteGuard always holds an exclusive lock.
1884        unsafe {
1885            self.rwlock.raw.unlock_exclusive();
1886        }
1887    }
1888}
1889
1890#[cfg(feature = "arc_lock")]
1891impl<R: RawRwLock, T: fmt::Debug + ?Sized> fmt::Debug for ArcRwLockWriteGuard<R, T> {
1892    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1893        fmt::Debug::fmt(&**self, f)
1894    }
1895}
1896
1897#[cfg(feature = "arc_lock")]
1898impl<R: RawRwLock, T: fmt::Display + ?Sized> fmt::Display for ArcRwLockWriteGuard<R, T> {
1899    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1900        (**self).fmt(f)
1901    }
1902}
1903
1904/// RAII structure used to release the upgradable read access of a lock when
1905/// dropped.
1906#[clippy::has_significant_drop]
1907#[must_use = "if unused the RwLock will immediately unlock"]
1908pub struct RwLockUpgradableReadGuard<'a, R: RawRwLockUpgrade, T: ?Sized> {
1909    rwlock: &'a RwLock<R, T>,
1910    marker: PhantomData<(&'a T, R::GuardMarker)>,
1911}
1912
1913unsafe impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + Sync + 'a> Sync
1914    for RwLockUpgradableReadGuard<'a, R, T>
1915{
1916}
1917
1918impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + 'a> RwLockUpgradableReadGuard<'a, R, T> {
1919    /// Returns a reference to the original reader-writer lock object.
1920    pub fn rwlock(s: &Self) -> &'a RwLock<R, T> {
1921        s.rwlock
1922    }
1923
1924    /// Temporarily unlocks the `RwLock` to execute the given function.
1925    ///
1926    /// This is safe because `&mut` guarantees that there exist no other
1927    /// references to the data protected by the `RwLock`.
1928    #[inline]
1929    pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
1930    where
1931        F: FnOnce() -> U,
1932    {
1933        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
1934        unsafe {
1935            s.rwlock.raw.unlock_upgradable();
1936        }
1937        defer!(s.rwlock.raw.lock_upgradable());
1938        f()
1939    }
1940
1941    /// Atomically upgrades an upgradable read lock lock into an exclusive write lock,
1942    /// blocking the current thread until it can be acquired.
1943    pub fn upgrade(s: Self) -> RwLockWriteGuard<'a, R, T> {
1944        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
1945        unsafe {
1946            s.rwlock.raw.upgrade();
1947        }
1948        let rwlock = s.rwlock;
1949        mem::forget(s);
1950        RwLockWriteGuard {
1951            rwlock,
1952            marker: PhantomData,
1953        }
1954    }
1955
1956    /// Tries to atomically upgrade an upgradable read lock into an exclusive write lock.
1957    ///
1958    /// If the access could not be granted at this time, then the current guard is returned.
1959    pub fn try_upgrade(s: Self) -> Result<RwLockWriteGuard<'a, R, T>, Self> {
1960        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
1961        if unsafe { s.rwlock.raw.try_upgrade() } {
1962            let rwlock = s.rwlock;
1963            mem::forget(s);
1964            Ok(RwLockWriteGuard {
1965                rwlock,
1966                marker: PhantomData,
1967            })
1968        } else {
1969            Err(s)
1970        }
1971    }
1972}
1973
1974impl<'a, R: RawRwLockUpgradeFair + 'a, T: ?Sized + 'a> RwLockUpgradableReadGuard<'a, R, T> {
1975    /// Unlocks the `RwLock` using a fair unlock protocol.
1976    ///
1977    /// By default, `RwLock` is unfair and allow the current thread to re-lock
1978    /// the `RwLock` before another has the chance to acquire the lock, even if
1979    /// that thread has been blocked on the `RwLock` for a long time. This is
1980    /// the default because it allows much higher throughput as it avoids
1981    /// forcing a context switch on every `RwLock` unlock. This can result in one
1982    /// thread acquiring a `RwLock` many more times than other threads.
1983    ///
1984    /// However in some cases it can be beneficial to ensure fairness by forcing
1985    /// the lock to pass on to a waiting thread if there is one. This is done by
1986    /// using this method instead of dropping the `RwLockUpgradableReadGuard` normally.
1987    #[inline]
1988    pub fn unlock_fair(s: Self) {
1989        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
1990        unsafe {
1991            s.rwlock.raw.unlock_upgradable_fair();
1992        }
1993        mem::forget(s);
1994    }
1995
1996    /// Temporarily unlocks the `RwLock` to execute the given function.
1997    ///
1998    /// The `RwLock` is unlocked a fair unlock protocol.
1999    ///
2000    /// This is safe because `&mut` guarantees that there exist no other
2001    /// references to the data protected by the `RwLock`.
2002    #[inline]
2003    pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
2004    where
2005        F: FnOnce() -> U,
2006    {
2007        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2008        unsafe {
2009            s.rwlock.raw.unlock_upgradable_fair();
2010        }
2011        defer!(s.rwlock.raw.lock_upgradable());
2012        f()
2013    }
2014
2015    /// Temporarily yields the `RwLock` to a waiting thread if there is one.
2016    ///
2017    /// This method is functionally equivalent to calling `unlock_fair` followed
2018    /// by `upgradable_read`, however it can be much more efficient in the case where there
2019    /// are no waiting threads.
2020    #[inline]
2021    pub fn bump(s: &mut Self) {
2022        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2023        unsafe {
2024            s.rwlock.raw.bump_upgradable();
2025        }
2026    }
2027}
2028
2029impl<'a, R: RawRwLockUpgradeDowngrade + 'a, T: ?Sized + 'a> RwLockUpgradableReadGuard<'a, R, T> {
2030    /// Atomically downgrades an upgradable read lock lock into a shared read lock
2031    /// without allowing any writers to take exclusive access of the lock in the
2032    /// meantime.
2033    ///
2034    /// Note that if there are any writers currently waiting to take the lock
2035    /// then other readers may not be able to acquire the lock even if it was
2036    /// downgraded.
2037    pub fn downgrade(s: Self) -> RwLockReadGuard<'a, R, T> {
2038        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2039        unsafe {
2040            s.rwlock.raw.downgrade_upgradable();
2041        }
2042        let rwlock = s.rwlock;
2043        mem::forget(s);
2044        RwLockReadGuard {
2045            rwlock,
2046            marker: PhantomData,
2047        }
2048    }
2049
2050    /// First, atomically upgrades an upgradable read lock lock into an exclusive write lock,
2051    /// blocking the current thread until it can be acquired.
2052    ///
2053    /// Then, calls the provided closure with an exclusive reference to the lock's data.
2054    ///
2055    /// Finally, atomically downgrades the lock back to an upgradable read lock.
2056    /// The closure's return value is wrapped in `Some` and returned.
2057    ///
2058    /// This function only requires a mutable reference to the guard, unlike
2059    /// `upgrade` which takes the guard by value.
2060    pub fn with_upgraded<Ret, F: FnOnce(&mut T) -> Ret>(&mut self, f: F) -> Ret {
2061        unsafe {
2062            self.rwlock.raw.upgrade();
2063        }
2064
2065        // Safety: We just upgraded the lock, so we have mutable access to the data.
2066        // This will restore the state the lock was in at the start of the function.
2067        defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() });
2068
2069        // Safety: We upgraded the lock, so we have mutable access to the data.
2070        // When this function returns, whether by drop or panic,
2071        // the drop guard will downgrade it back to an upgradeable lock.
2072        f(unsafe { &mut *self.rwlock.data.get() })
2073    }
2074
2075    /// First, tries to atomically upgrade an upgradable read lock into an exclusive write lock.
2076    ///
2077    /// If the access could not be granted at this time, then `None` is returned.
2078    ///
2079    /// Otherwise, calls the provided closure with an exclusive reference to the lock's data,
2080    /// and finally downgrades the lock back to an upgradable read lock.
2081    /// The closure's return value is wrapped in `Some` and returned.
2082    ///
2083    /// This function only requires a mutable reference to the guard, unlike
2084    /// `try_upgrade` which takes the guard by value.
2085    pub fn try_with_upgraded<Ret, F: FnOnce(&mut T) -> Ret>(&mut self, f: F) -> Option<Ret> {
2086        if unsafe { self.rwlock.raw.try_upgrade() } {
2087            // Safety: We just upgraded the lock, so we have mutable access to the data.
2088            // This will restore the state the lock was in at the start of the function.
2089            defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() });
2090
2091            // Safety: We upgraded the lock, so we have mutable access to the data.
2092            // When this function returns, whether by drop or panic,
2093            // the drop guard will downgrade it back to an upgradeable lock.
2094            Some(f(unsafe { &mut *self.rwlock.data.get() }))
2095        } else {
2096            None
2097        }
2098    }
2099}
2100
2101impl<'a, R: RawRwLockUpgradeTimed + 'a, T: ?Sized + 'a> RwLockUpgradableReadGuard<'a, R, T> {
2102    /// Tries to atomically upgrade an upgradable read lock into an exclusive
2103    /// write lock, until a timeout is reached.
2104    ///
2105    /// If the access could not be granted before the timeout expires, then
2106    /// the current guard is returned.
2107    pub fn try_upgrade_for(
2108        s: Self,
2109        timeout: R::Duration,
2110    ) -> Result<RwLockWriteGuard<'a, R, T>, Self> {
2111        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2112        if unsafe { s.rwlock.raw.try_upgrade_for(timeout) } {
2113            let rwlock = s.rwlock;
2114            mem::forget(s);
2115            Ok(RwLockWriteGuard {
2116                rwlock,
2117                marker: PhantomData,
2118            })
2119        } else {
2120            Err(s)
2121        }
2122    }
2123
2124    /// Tries to atomically upgrade an upgradable read lock into an exclusive
2125    /// write lock, until a timeout is reached.
2126    ///
2127    /// If the access could not be granted before the timeout expires, then
2128    /// the current guard is returned.
2129    #[inline]
2130    pub fn try_upgrade_until(
2131        s: Self,
2132        timeout: R::Instant,
2133    ) -> Result<RwLockWriteGuard<'a, R, T>, Self> {
2134        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2135        if unsafe { s.rwlock.raw.try_upgrade_until(timeout) } {
2136            let rwlock = s.rwlock;
2137            mem::forget(s);
2138            Ok(RwLockWriteGuard {
2139                rwlock,
2140                marker: PhantomData,
2141            })
2142        } else {
2143            Err(s)
2144        }
2145    }
2146}
2147
2148impl<'a, R: RawRwLockUpgradeTimed + RawRwLockUpgradeDowngrade + 'a, T: ?Sized + 'a>
2149    RwLockUpgradableReadGuard<'a, R, T>
2150{
2151    /// Tries to atomically upgrade an upgradable read lock into an exclusive
2152    /// write lock, until a timeout is reached.
2153    ///
2154    /// If the access could not be granted before the timeout expires, then
2155    /// `None` is returned.
2156    ///
2157    /// Otherwise, calls the provided closure with an exclusive reference to the lock's data,
2158    /// and finally downgrades the lock back to an upgradable read lock.
2159    /// The closure's return value is wrapped in `Some` and returned.
2160    ///
2161    /// This function only requires a mutable reference to the guard, unlike
2162    /// `try_upgrade_for` which takes the guard by value.
2163    pub fn try_with_upgraded_for<Ret, F: FnOnce(&mut T) -> Ret>(
2164        &mut self,
2165        timeout: R::Duration,
2166        f: F,
2167    ) -> Option<Ret> {
2168        if unsafe { self.rwlock.raw.try_upgrade_for(timeout) } {
2169            // Safety: We just upgraded the lock, so we have mutable access to the data.
2170            // This will restore the state the lock was in at the start of the function.
2171            defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() });
2172
2173            // Safety: We upgraded the lock, so we have mutable access to the data.
2174            // When this function returns, whether by drop or panic,
2175            // the drop guard will downgrade it back to an upgradeable lock.
2176            Some(f(unsafe { &mut *self.rwlock.data.get() }))
2177        } else {
2178            None
2179        }
2180    }
2181
2182    /// Tries to atomically upgrade an upgradable read lock into an exclusive
2183    /// write lock, until a timeout is reached.
2184    ///
2185    /// If the access could not be granted before the timeout expires, then
2186    /// `None` is returned.
2187    ///
2188    /// Otherwise, calls the provided closure with an exclusive reference to the lock's data,
2189    /// and finally downgrades the lock back to an upgradable read lock.
2190    /// The closure's return value is wrapped in `Some` and returned.
2191    ///
2192    /// This function only requires a mutable reference to the guard, unlike
2193    /// `try_upgrade_until` which takes the guard by value.
2194    pub fn try_with_upgraded_until<Ret, F: FnOnce(&mut T) -> Ret>(
2195        &mut self,
2196        timeout: R::Instant,
2197        f: F,
2198    ) -> Option<Ret> {
2199        if unsafe { self.rwlock.raw.try_upgrade_until(timeout) } {
2200            // Safety: We just upgraded the lock, so we have mutable access to the data.
2201            // This will restore the state the lock was in at the start of the function.
2202            defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() });
2203
2204            // Safety: We upgraded the lock, so we have mutable access to the data.
2205            // When this function returns, whether by drop or panic,
2206            // the drop guard will downgrade it back to an upgradeable lock.
2207            Some(f(unsafe { &mut *self.rwlock.data.get() }))
2208        } else {
2209            None
2210        }
2211    }
2212}
2213
2214impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + 'a> Deref for RwLockUpgradableReadGuard<'a, R, T> {
2215    type Target = T;
2216    #[inline]
2217    fn deref(&self) -> &T {
2218        unsafe { &*self.rwlock.data.get() }
2219    }
2220}
2221
2222impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + 'a> Drop for RwLockUpgradableReadGuard<'a, R, T> {
2223    #[inline]
2224    fn drop(&mut self) {
2225        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2226        unsafe {
2227            self.rwlock.raw.unlock_upgradable();
2228        }
2229    }
2230}
2231
2232impl<'a, R: RawRwLockUpgrade + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug
2233    for RwLockUpgradableReadGuard<'a, R, T>
2234{
2235    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2236        fmt::Debug::fmt(&**self, f)
2237    }
2238}
2239
2240impl<'a, R: RawRwLockUpgrade + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display
2241    for RwLockUpgradableReadGuard<'a, R, T>
2242{
2243    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2244        (**self).fmt(f)
2245    }
2246}
2247
2248#[cfg(feature = "owning_ref")]
2249unsafe impl<'a, R: RawRwLockUpgrade + 'a, T: ?Sized + 'a> StableAddress
2250    for RwLockUpgradableReadGuard<'a, R, T>
2251{
2252}
2253
2254/// An RAII rwlock guard returned by the `Arc` locking operations on `RwLock`.
2255/// This is similar to the `RwLockUpgradableReadGuard` struct, except instead of using a reference to unlock the
2256/// `RwLock` it uses an `Arc<RwLock>`. This has several advantages, most notably that it has an `'static`
2257/// lifetime.
2258#[cfg(feature = "arc_lock")]
2259#[clippy::has_significant_drop]
2260#[must_use = "if unused the RwLock will immediately unlock"]
2261pub struct ArcRwLockUpgradableReadGuard<R: RawRwLockUpgrade, T: ?Sized> {
2262    rwlock: Arc<RwLock<R, T>>,
2263    marker: PhantomData<R::GuardMarker>,
2264}
2265
2266#[cfg(feature = "arc_lock")]
2267impl<R: RawRwLockUpgrade, T: ?Sized> ArcRwLockUpgradableReadGuard<R, T> {
2268    /// Returns a reference to the rwlock, contained in its original `Arc`.
2269    pub fn rwlock(s: &Self) -> &Arc<RwLock<R, T>> {
2270        &s.rwlock
2271    }
2272
2273    /// Temporarily unlocks the `RwLock` to execute the given function.
2274    ///
2275    /// This is functionally identical to the `unlocked` method on [`RwLockUpgradableReadGuard`].
2276    #[inline]
2277    pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
2278    where
2279        F: FnOnce() -> U,
2280    {
2281        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2282        unsafe {
2283            s.rwlock.raw.unlock_upgradable();
2284        }
2285        defer!(s.rwlock.raw.lock_upgradable());
2286        f()
2287    }
2288
2289    /// Atomically upgrades an upgradable read lock lock into an exclusive write lock,
2290    /// blocking the current thread until it can be acquired.
2291    pub fn upgrade(s: Self) -> ArcRwLockWriteGuard<R, T> {
2292        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2293        unsafe {
2294            s.rwlock.raw.upgrade();
2295        }
2296
2297        // SAFETY: avoid incrementing or decrementing the refcount using ManuallyDrop and reading the Arc out
2298        //         of the struct
2299        let s = ManuallyDrop::new(s);
2300        let rwlock = unsafe { ptr::read(&s.rwlock) };
2301
2302        ArcRwLockWriteGuard {
2303            rwlock,
2304            marker: PhantomData,
2305        }
2306    }
2307
2308    /// Tries to atomically upgrade an upgradable read lock into an exclusive write lock.
2309    ///
2310    /// If the access could not be granted at this time, then the current guard is returned.
2311    pub fn try_upgrade(s: Self) -> Result<ArcRwLockWriteGuard<R, T>, Self> {
2312        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2313        if unsafe { s.rwlock.raw.try_upgrade() } {
2314            // SAFETY: same as above
2315            let s = ManuallyDrop::new(s);
2316            let rwlock = unsafe { ptr::read(&s.rwlock) };
2317
2318            Ok(ArcRwLockWriteGuard {
2319                rwlock,
2320                marker: PhantomData,
2321            })
2322        } else {
2323            Err(s)
2324        }
2325    }
2326}
2327
2328#[cfg(feature = "arc_lock")]
2329impl<R: RawRwLockUpgradeFair, T: ?Sized> ArcRwLockUpgradableReadGuard<R, T> {
2330    /// Unlocks the `RwLock` using a fair unlock protocol.
2331    ///
2332    /// This is functionally identical to the `unlock_fair` method on [`RwLockUpgradableReadGuard`].
2333    #[inline]
2334    pub fn unlock_fair(s: Self) {
2335        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2336        unsafe {
2337            s.rwlock.raw.unlock_upgradable_fair();
2338        }
2339
2340        // SAFETY: make sure we decrement the refcount properly
2341        let mut s = ManuallyDrop::new(s);
2342        unsafe { ptr::drop_in_place(&mut s.rwlock) };
2343    }
2344
2345    /// Temporarily unlocks the `RwLock` to execute the given function.
2346    ///
2347    /// This is functionally equivalent to the `unlocked_fair` method on [`RwLockUpgradableReadGuard`].
2348    #[inline]
2349    pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
2350    where
2351        F: FnOnce() -> U,
2352    {
2353        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2354        unsafe {
2355            s.rwlock.raw.unlock_upgradable_fair();
2356        }
2357        defer!(s.rwlock.raw.lock_upgradable());
2358        f()
2359    }
2360
2361    /// Temporarily yields the `RwLock` to a waiting thread if there is one.
2362    ///
2363    /// This method is functionally equivalent to calling `bump` on [`RwLockUpgradableReadGuard`].
2364    #[inline]
2365    pub fn bump(s: &mut Self) {
2366        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2367        unsafe {
2368            s.rwlock.raw.bump_upgradable();
2369        }
2370    }
2371}
2372
2373#[cfg(feature = "arc_lock")]
2374impl<R: RawRwLockUpgradeDowngrade, T: ?Sized> ArcRwLockUpgradableReadGuard<R, T> {
2375    /// Atomically downgrades an upgradable read lock lock into a shared read lock
2376    /// without allowing any writers to take exclusive access of the lock in the
2377    /// meantime.
2378    ///
2379    /// Note that if there are any writers currently waiting to take the lock
2380    /// then other readers may not be able to acquire the lock even if it was
2381    /// downgraded.
2382    pub fn downgrade(s: Self) -> ArcRwLockReadGuard<R, T> {
2383        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2384        unsafe {
2385            s.rwlock.raw.downgrade_upgradable();
2386        }
2387
2388        // SAFETY: use ManuallyDrop and ptr::read to ensure the refcount is not changed
2389        let s = ManuallyDrop::new(s);
2390        let rwlock = unsafe { ptr::read(&s.rwlock) };
2391
2392        ArcRwLockReadGuard {
2393            rwlock,
2394            marker: PhantomData,
2395        }
2396    }
2397
2398    /// First, atomically upgrades an upgradable read lock lock into an exclusive write lock,
2399    /// blocking the current thread until it can be acquired.
2400    ///
2401    /// Then, calls the provided closure with an exclusive reference to the lock's data.
2402    ///
2403    /// Finally, atomically downgrades the lock back to an upgradable read lock.
2404    /// The closure's return value is returned.
2405    ///
2406    /// This function only requires a mutable reference to the guard, unlike
2407    /// `upgrade` which takes the guard by value.
2408    pub fn with_upgraded<Ret, F: FnOnce(&mut T) -> Ret>(&mut self, f: F) -> Ret {
2409        unsafe {
2410            self.rwlock.raw.upgrade();
2411        }
2412
2413        // Safety: We just upgraded the lock, so we have mutable access to the data.
2414        // This will restore the state the lock was in at the start of the function.
2415        defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() });
2416
2417        // Safety: We upgraded the lock, so we have mutable access to the data.
2418        // When this function returns, whether by drop or panic,
2419        // the drop guard will downgrade it back to an upgradeable lock.
2420        f(unsafe { &mut *self.rwlock.data.get() })
2421    }
2422
2423    /// First, tries to atomically upgrade an upgradable read lock into an exclusive write lock.
2424    ///
2425    /// If the access could not be granted at this time, then `None` is returned.
2426    ///
2427    /// Otherwise, calls the provided closure with an exclusive reference to the lock's data,
2428    /// and finally downgrades the lock back to an upgradable read lock.
2429    /// The closure's return value is wrapped in `Some` and returned.
2430    ///
2431    /// This function only requires a mutable reference to the guard, unlike
2432    /// `try_upgrade` which takes the guard by value.
2433    pub fn try_with_upgraded<Ret, F: FnOnce(&mut T) -> Ret>(&mut self, f: F) -> Option<Ret> {
2434        if unsafe { self.rwlock.raw.try_upgrade() } {
2435            // Safety: We just upgraded the lock, so we have mutable access to the data.
2436            // This will restore the state the lock was in at the start of the function.
2437            defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() });
2438
2439            // Safety: We upgraded the lock, so we have mutable access to the data.
2440            // When this function returns, whether by drop or panic,
2441            // the drop guard will downgrade it back to an upgradeable lock.
2442            Some(f(unsafe { &mut *self.rwlock.data.get() }))
2443        } else {
2444            None
2445        }
2446    }
2447}
2448
2449#[cfg(feature = "arc_lock")]
2450impl<R: RawRwLockUpgradeTimed, T: ?Sized> ArcRwLockUpgradableReadGuard<R, T> {
2451    /// Tries to atomically upgrade an upgradable read lock into an exclusive
2452    /// write lock, until a timeout is reached.
2453    ///
2454    /// If the access could not be granted before the timeout expires, then
2455    /// the current guard is returned.
2456    pub fn try_upgrade_for(
2457        s: Self,
2458        timeout: R::Duration,
2459    ) -> Result<ArcRwLockWriteGuard<R, T>, Self> {
2460        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2461        if unsafe { s.rwlock.raw.try_upgrade_for(timeout) } {
2462            // SAFETY: same as above
2463            let s = ManuallyDrop::new(s);
2464            let rwlock = unsafe { ptr::read(&s.rwlock) };
2465
2466            Ok(ArcRwLockWriteGuard {
2467                rwlock,
2468                marker: PhantomData,
2469            })
2470        } else {
2471            Err(s)
2472        }
2473    }
2474
2475    /// Tries to atomically upgrade an upgradable read lock into an exclusive
2476    /// write lock, until a timeout is reached.
2477    ///
2478    /// If the access could not be granted before the timeout expires, then
2479    /// the current guard is returned.
2480    #[inline]
2481    pub fn try_upgrade_until(
2482        s: Self,
2483        timeout: R::Instant,
2484    ) -> Result<ArcRwLockWriteGuard<R, T>, Self> {
2485        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2486        if unsafe { s.rwlock.raw.try_upgrade_until(timeout) } {
2487            // SAFETY: same as above
2488            let s = ManuallyDrop::new(s);
2489            let rwlock = unsafe { ptr::read(&s.rwlock) };
2490
2491            Ok(ArcRwLockWriteGuard {
2492                rwlock,
2493                marker: PhantomData,
2494            })
2495        } else {
2496            Err(s)
2497        }
2498    }
2499}
2500
2501#[cfg(feature = "arc_lock")]
2502impl<R: RawRwLockUpgradeTimed + RawRwLockUpgradeDowngrade, T: ?Sized>
2503    ArcRwLockUpgradableReadGuard<R, T>
2504{
2505    /// Tries to atomically upgrade an upgradable read lock into an exclusive
2506    /// write lock, until a timeout is reached.
2507    ///
2508    /// If the access could not be granted before the timeout expires, then
2509    /// `None` is returned.
2510    ///
2511    /// Otherwise, calls the provided closure with an exclusive reference to the lock's data,
2512    /// and finally downgrades the lock back to an upgradable read lock.
2513    /// The closure's return value is wrapped in `Some` and returned.
2514    ///
2515    /// This function only requires a mutable reference to the guard, unlike
2516    /// `try_upgrade_for` which takes the guard by value.
2517    pub fn try_with_upgraded_for<Ret, F: FnOnce(&mut T) -> Ret>(
2518        &mut self,
2519        timeout: R::Duration,
2520        f: F,
2521    ) -> Option<Ret> {
2522        if unsafe { self.rwlock.raw.try_upgrade_for(timeout) } {
2523            // Safety: We just upgraded the lock, so we have mutable access to the data.
2524            // This will restore the state the lock was in at the start of the function.
2525            defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() });
2526
2527            // Safety: We upgraded the lock, so we have mutable access to the data.
2528            // When this function returns, whether by drop or panic,
2529            // the drop guard will downgrade it back to an upgradeable lock.
2530            Some(f(unsafe { &mut *self.rwlock.data.get() }))
2531        } else {
2532            None
2533        }
2534    }
2535
2536    /// Tries to atomically upgrade an upgradable read lock into an exclusive
2537    /// write lock, until a timeout is reached.
2538    ///
2539    /// If the access could not be granted before the timeout expires, then
2540    /// `None` is returned.
2541    ///
2542    /// Otherwise, calls the provided closure with an exclusive reference to the lock's data,
2543    /// and finally downgrades the lock back to an upgradable read lock.
2544    /// The closure's return value is wrapped in `Some` and returned.
2545    ///
2546    /// This function only requires a mutable reference to the guard, unlike
2547    /// `try_upgrade_until` which takes the guard by value.
2548    pub fn try_with_upgraded_until<Ret, F: FnOnce(&mut T) -> Ret>(
2549        &mut self,
2550        timeout: R::Instant,
2551        f: F,
2552    ) -> Option<Ret> {
2553        if unsafe { self.rwlock.raw.try_upgrade_until(timeout) } {
2554            // Safety: We just upgraded the lock, so we have mutable access to the data.
2555            // This will restore the state the lock was in at the start of the function.
2556            defer!(unsafe { self.rwlock.raw.downgrade_to_upgradable() });
2557
2558            // Safety: We upgraded the lock, so we have mutable access to the data.
2559            // When this function returns, whether by drop or panic,
2560            // the drop guard will downgrade it back to an upgradeable lock.
2561            Some(f(unsafe { &mut *self.rwlock.data.get() }))
2562        } else {
2563            None
2564        }
2565    }
2566}
2567
2568#[cfg(feature = "arc_lock")]
2569impl<R: RawRwLockUpgrade, T: ?Sized> Deref for ArcRwLockUpgradableReadGuard<R, T> {
2570    type Target = T;
2571    #[inline]
2572    fn deref(&self) -> &T {
2573        unsafe { &*self.rwlock.data.get() }
2574    }
2575}
2576
2577#[cfg(feature = "arc_lock")]
2578impl<R: RawRwLockUpgrade, T: ?Sized> Drop for ArcRwLockUpgradableReadGuard<R, T> {
2579    #[inline]
2580    fn drop(&mut self) {
2581        // Safety: An RwLockUpgradableReadGuard always holds an upgradable lock.
2582        unsafe {
2583            self.rwlock.raw.unlock_upgradable();
2584        }
2585    }
2586}
2587
2588#[cfg(feature = "arc_lock")]
2589impl<R: RawRwLockUpgrade, T: fmt::Debug + ?Sized> fmt::Debug
2590    for ArcRwLockUpgradableReadGuard<R, T>
2591{
2592    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2593        fmt::Debug::fmt(&**self, f)
2594    }
2595}
2596
2597#[cfg(feature = "arc_lock")]
2598impl<R: RawRwLockUpgrade, T: fmt::Display + ?Sized> fmt::Display
2599    for ArcRwLockUpgradableReadGuard<R, T>
2600{
2601    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2602        (**self).fmt(f)
2603    }
2604}
2605
2606/// An RAII read lock guard returned by `RwLockReadGuard::map`, which can point to a
2607/// subfield of the protected data.
2608///
2609/// The main difference between `MappedRwLockReadGuard` and `RwLockReadGuard` is that the
2610/// former doesn't support temporarily unlocking and re-locking, since that
2611/// could introduce soundness issues if the locked object is modified by another
2612/// thread.
2613#[clippy::has_significant_drop]
2614#[must_use = "if unused the RwLock will immediately unlock"]
2615pub struct MappedRwLockReadGuard<'a, R: RawRwLock, T: ?Sized> {
2616    raw: &'a R,
2617    data: *const T,
2618    marker: PhantomData<&'a T>,
2619}
2620
2621unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + Sync + 'a> Sync for MappedRwLockReadGuard<'a, R, T> {}
2622unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + Sync + 'a> Send for MappedRwLockReadGuard<'a, R, T> where
2623    R::GuardMarker: Send
2624{
2625}
2626
2627impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> MappedRwLockReadGuard<'a, R, T> {
2628    /// Make a new `MappedRwLockReadGuard` for a component of the locked data.
2629    ///
2630    /// This operation cannot fail as the `MappedRwLockReadGuard` passed
2631    /// in already locked the data.
2632    ///
2633    /// This is an associated function that needs to be
2634    /// used as `MappedRwLockReadGuard::map(...)`. A method would interfere with methods of
2635    /// the same name on the contents of the locked data.
2636    #[inline]
2637    pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedRwLockReadGuard<'a, R, U>
2638    where
2639        F: FnOnce(&T) -> &U,
2640    {
2641        let raw = s.raw;
2642        let data = f(unsafe { &*s.data });
2643        mem::forget(s);
2644        MappedRwLockReadGuard {
2645            raw,
2646            data,
2647            marker: PhantomData,
2648        }
2649    }
2650
2651    /// Attempts to make  a new `MappedRwLockReadGuard` for a component of the
2652    /// locked data. The original guard is return if the closure returns `None`.
2653    ///
2654    /// This operation cannot fail as the `MappedRwLockReadGuard` passed
2655    /// in already locked the data.
2656    ///
2657    /// This is an associated function that needs to be
2658    /// used as `MappedRwLockReadGuard::try_map(...)`. A method would interfere with methods of
2659    /// the same name on the contents of the locked data.
2660    #[inline]
2661    pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockReadGuard<'a, R, U>, Self>
2662    where
2663        F: FnOnce(&T) -> Option<&U>,
2664    {
2665        let raw = s.raw;
2666        let data = match f(unsafe { &*s.data }) {
2667            Some(data) => data,
2668            None => return Err(s),
2669        };
2670        mem::forget(s);
2671        Ok(MappedRwLockReadGuard {
2672            raw,
2673            data,
2674            marker: PhantomData,
2675        })
2676    }
2677}
2678
2679impl<'a, R: RawRwLockFair + 'a, T: ?Sized + 'a> MappedRwLockReadGuard<'a, R, T> {
2680    /// Unlocks the `RwLock` using a fair unlock protocol.
2681    ///
2682    /// By default, `RwLock` is unfair and allow the current thread to re-lock
2683    /// the `RwLock` before another has the chance to acquire the lock, even if
2684    /// that thread has been blocked on the `RwLock` for a long time. This is
2685    /// the default because it allows much higher throughput as it avoids
2686    /// forcing a context switch on every `RwLock` unlock. This can result in one
2687    /// thread acquiring a `RwLock` many more times than other threads.
2688    ///
2689    /// However in some cases it can be beneficial to ensure fairness by forcing
2690    /// the lock to pass on to a waiting thread if there is one. This is done by
2691    /// using this method instead of dropping the `MappedRwLockReadGuard` normally.
2692    #[inline]
2693    pub fn unlock_fair(s: Self) {
2694        // Safety: A MappedRwLockReadGuard always holds a shared lock.
2695        unsafe {
2696            s.raw.unlock_shared_fair();
2697        }
2698        mem::forget(s);
2699    }
2700}
2701
2702impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Deref for MappedRwLockReadGuard<'a, R, T> {
2703    type Target = T;
2704    #[inline]
2705    fn deref(&self) -> &T {
2706        unsafe { &*self.data }
2707    }
2708}
2709
2710impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for MappedRwLockReadGuard<'a, R, T> {
2711    #[inline]
2712    fn drop(&mut self) {
2713        // Safety: A MappedRwLockReadGuard always holds a shared lock.
2714        unsafe {
2715            self.raw.unlock_shared();
2716        }
2717    }
2718}
2719
2720impl<'a, R: RawRwLock + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug
2721    for MappedRwLockReadGuard<'a, R, T>
2722{
2723    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2724        fmt::Debug::fmt(&**self, f)
2725    }
2726}
2727
2728impl<'a, R: RawRwLock + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display
2729    for MappedRwLockReadGuard<'a, R, T>
2730{
2731    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2732        (**self).fmt(f)
2733    }
2734}
2735
2736#[cfg(feature = "owning_ref")]
2737unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> StableAddress
2738    for MappedRwLockReadGuard<'a, R, T>
2739{
2740}
2741
2742/// An RAII write lock guard returned by `RwLockWriteGuard::map`, which can point to a
2743/// subfield of the protected data.
2744///
2745/// The main difference between `MappedRwLockWriteGuard` and `RwLockWriteGuard` is that the
2746/// former doesn't support temporarily unlocking and re-locking, since that
2747/// could introduce soundness issues if the locked object is modified by another
2748/// thread.
2749#[clippy::has_significant_drop]
2750#[must_use = "if unused the RwLock will immediately unlock"]
2751pub struct MappedRwLockWriteGuard<'a, R: RawRwLock, T: ?Sized> {
2752    raw: &'a R,
2753    data: *mut T,
2754    marker: PhantomData<&'a mut T>,
2755}
2756
2757unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + Sync + 'a> Sync
2758    for MappedRwLockWriteGuard<'a, R, T>
2759{
2760}
2761unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + Send + 'a> Send for MappedRwLockWriteGuard<'a, R, T> where
2762    R::GuardMarker: Send
2763{
2764}
2765
2766impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> MappedRwLockWriteGuard<'a, R, T> {
2767    /// Make a new `MappedRwLockWriteGuard` for a component of the locked data.
2768    ///
2769    /// This operation cannot fail as the `MappedRwLockWriteGuard` passed
2770    /// in already locked the data.
2771    ///
2772    /// This is an associated function that needs to be
2773    /// used as `MappedRwLockWriteGuard::map(...)`. A method would interfere with methods of
2774    /// the same name on the contents of the locked data.
2775    #[inline]
2776    pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedRwLockWriteGuard<'a, R, U>
2777    where
2778        F: FnOnce(&mut T) -> &mut U,
2779    {
2780        let raw = s.raw;
2781        let data = f(unsafe { &mut *s.data });
2782        mem::forget(s);
2783        MappedRwLockWriteGuard {
2784            raw,
2785            data,
2786            marker: PhantomData,
2787        }
2788    }
2789
2790    /// Attempts to make  a new `MappedRwLockWriteGuard` for a component of the
2791    /// locked data. The original guard is return if the closure returns `None`.
2792    ///
2793    /// This operation cannot fail as the `MappedRwLockWriteGuard` passed
2794    /// in already locked the data.
2795    ///
2796    /// This is an associated function that needs to be
2797    /// used as `MappedRwLockWriteGuard::try_map(...)`. A method would interfere with methods of
2798    /// the same name on the contents of the locked data.
2799    #[inline]
2800    pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, R, U>, Self>
2801    where
2802        F: FnOnce(&mut T) -> Option<&mut U>,
2803    {
2804        let raw = s.raw;
2805        let data = match f(unsafe { &mut *s.data }) {
2806            Some(data) => data,
2807            None => return Err(s),
2808        };
2809        mem::forget(s);
2810        Ok(MappedRwLockWriteGuard {
2811            raw,
2812            data,
2813            marker: PhantomData,
2814        })
2815    }
2816}
2817
2818impl<'a, R: RawRwLockFair + 'a, T: ?Sized + 'a> MappedRwLockWriteGuard<'a, R, T> {
2819    /// Unlocks the `RwLock` using a fair unlock protocol.
2820    ///
2821    /// By default, `RwLock` is unfair and allow the current thread to re-lock
2822    /// the `RwLock` before another has the chance to acquire the lock, even if
2823    /// that thread has been blocked on the `RwLock` for a long time. This is
2824    /// the default because it allows much higher throughput as it avoids
2825    /// forcing a context switch on every `RwLock` unlock. This can result in one
2826    /// thread acquiring a `RwLock` many more times than other threads.
2827    ///
2828    /// However in some cases it can be beneficial to ensure fairness by forcing
2829    /// the lock to pass on to a waiting thread if there is one. This is done by
2830    /// using this method instead of dropping the `MappedRwLockWriteGuard` normally.
2831    #[inline]
2832    pub fn unlock_fair(s: Self) {
2833        // Safety: A MappedRwLockWriteGuard always holds an exclusive lock.
2834        unsafe {
2835            s.raw.unlock_exclusive_fair();
2836        }
2837        mem::forget(s);
2838    }
2839}
2840
2841impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Deref for MappedRwLockWriteGuard<'a, R, T> {
2842    type Target = T;
2843    #[inline]
2844    fn deref(&self) -> &T {
2845        unsafe { &*self.data }
2846    }
2847}
2848
2849impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> DerefMut for MappedRwLockWriteGuard<'a, R, T> {
2850    #[inline]
2851    fn deref_mut(&mut self) -> &mut T {
2852        unsafe { &mut *self.data }
2853    }
2854}
2855
2856impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> Drop for MappedRwLockWriteGuard<'a, R, T> {
2857    #[inline]
2858    fn drop(&mut self) {
2859        // Safety: A MappedRwLockWriteGuard always holds an exclusive lock.
2860        unsafe {
2861            self.raw.unlock_exclusive();
2862        }
2863    }
2864}
2865
2866impl<'a, R: RawRwLock + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug
2867    for MappedRwLockWriteGuard<'a, R, T>
2868{
2869    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2870        fmt::Debug::fmt(&**self, f)
2871    }
2872}
2873
2874impl<'a, R: RawRwLock + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display
2875    for MappedRwLockWriteGuard<'a, R, T>
2876{
2877    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2878        (**self).fmt(f)
2879    }
2880}
2881
2882#[cfg(feature = "owning_ref")]
2883unsafe impl<'a, R: RawRwLock + 'a, T: ?Sized + 'a> StableAddress
2884    for MappedRwLockWriteGuard<'a, R, T>
2885{
2886}