async_rwlock/
lib.rs

1//! An async reader-writer lock.
2//!
3//! This type of lock allows multiple readers or one writer at any point in time.
4//!
5//! The locking strategy is write-preferring, which means writers are never starved.
6//! Releasing a write lock wakes the next blocked reader and the next blocked writer.
7//!
8//! # Examples
9//!
10//! ```
11//! # futures_lite::future::block_on(async {
12//! use async_rwlock::RwLock;
13//!
14//! let lock = RwLock::new(5);
15//!
16//! // Multiple read locks can be held at a time.
17//! let r1 = lock.read().await;
18//! let r2 = lock.read().await;
19//! assert_eq!(*r1, 5);
20//! assert_eq!(*r2, 5);
21//! drop((r1, r2));
22//!
23//! // Only one write lock can be held at a time.
24//! let mut w = lock.write().await;
25//! *w += 1;
26//! assert_eq!(*w, 6);
27//! # })
28//! ```
29
30#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)]
31
32use std::cell::UnsafeCell;
33use std::fmt;
34use std::mem;
35use std::ops::{Deref, DerefMut};
36use std::process;
37use std::sync::atomic::{AtomicUsize, Ordering};
38
39use async_mutex::{Mutex, MutexGuard};
40use event_listener::Event;
41
42const WRITER_BIT: usize = 1;
43const ONE_READER: usize = 2;
44
45/// An async reader-writer lock.
46///
47/// # Examples
48///
49/// ```
50/// # futures_lite::future::block_on(async {
51/// use async_rwlock::RwLock;
52///
53/// let lock = RwLock::new(5);
54///
55/// // Multiple read locks can be held at a time.
56/// let r1 = lock.read().await;
57/// let r2 = lock.read().await;
58/// assert_eq!(*r1, 5);
59/// assert_eq!(*r2, 5);
60/// drop((r1, r2));
61///
62/// // Only one write locks can be held at a time.
63/// let mut w = lock.write().await;
64/// *w += 1;
65/// assert_eq!(*w, 6);
66/// # })
67/// ```
68pub struct RwLock<T: ?Sized> {
69    /// Acquired by the writer.
70    mutex: Mutex<()>,
71
72    /// Event triggered when the last reader is dropped.
73    no_readers: Event,
74
75    /// Event triggered when the writer is dropped.
76    no_writer: Event,
77
78    /// Current state of the lock.
79    ///
80    /// The least significant bit (`WRITER_BIT`) is set to 1 when a writer is holding the lock or
81    /// trying to acquire it.
82    ///
83    /// The upper bits contain the number of currently active readers. Each active reader
84    /// increments the state by `ONE_READER`.
85    state: AtomicUsize,
86
87    /// The inner value.
88    value: UnsafeCell<T>,
89}
90
91unsafe impl<T: Send + ?Sized> Send for RwLock<T> {}
92unsafe impl<T: Send + Sync + ?Sized> Sync for RwLock<T> {}
93
94impl<T> RwLock<T> {
95    /// Creates a new reader-writer lock.
96    ///
97    /// # Examples
98    ///
99    /// ```
100    /// use async_rwlock::RwLock;
101    ///
102    /// let lock = RwLock::new(0);
103    /// ```
104    pub const fn new(t: T) -> RwLock<T> {
105        RwLock {
106            mutex: Mutex::new(()),
107            no_readers: Event::new(),
108            no_writer: Event::new(),
109            state: AtomicUsize::new(0),
110            value: UnsafeCell::new(t),
111        }
112    }
113
114    /// Unwraps the lock and returns the inner value.
115    ///
116    /// # Examples
117    ///
118    /// ```
119    /// use async_rwlock::RwLock;
120    ///
121    /// let lock = RwLock::new(5);
122    /// assert_eq!(lock.into_inner(), 5);
123    /// ```
124    pub fn into_inner(self) -> T {
125        self.value.into_inner()
126    }
127}
128
129impl<T: ?Sized> RwLock<T> {
130    /// Attempts to acquire a read lock.
131    ///
132    /// If a read lock could not be acquired at this time, then [`None`] is returned. Otherwise, a
133    /// guard is returned that releases the lock when dropped.
134    ///
135    /// # Examples
136    ///
137    /// ```
138    /// # futures_lite::future::block_on(async {
139    /// use async_rwlock::RwLock;
140    ///
141    /// let lock = RwLock::new(1);
142    ///
143    /// let reader = lock.read().await;
144    /// assert_eq!(*reader, 1);
145    ///
146    /// assert!(lock.try_read().is_some());
147    /// # })
148    /// ```
149    pub fn try_read(&self) -> Option<RwLockReadGuard<'_, T>> {
150        let mut state = self.state.load(Ordering::Acquire);
151
152        loop {
153            // If there's a writer holding the lock or attempting to acquire it, we cannot acquire
154            // a read lock here.
155            if state & WRITER_BIT != 0 {
156                return None;
157            }
158
159            // Make sure the number of readers doesn't overflow.
160            if state > std::isize::MAX as usize {
161                process::abort();
162            }
163
164            // Increment the number of readers.
165            match self.state.compare_exchange(
166                state,
167                state + ONE_READER,
168                Ordering::AcqRel,
169                Ordering::Acquire,
170            ) {
171                Ok(_) => return Some(RwLockReadGuard(self)),
172                Err(s) => state = s,
173            }
174        }
175    }
176
177    /// Acquires a read lock.
178    ///
179    /// Returns a guard that releases the lock when dropped.
180    ///
181    /// Note that attempts to acquire a read lock will block if there are also concurrent attempts
182    /// to acquire a write lock.
183    ///
184    /// # Examples
185    ///
186    /// ```
187    /// # futures_lite::future::block_on(async {
188    /// use async_rwlock::RwLock;
189    ///
190    /// let lock = RwLock::new(1);
191    ///
192    /// let reader = lock.read().await;
193    /// assert_eq!(*reader, 1);
194    ///
195    /// assert!(lock.try_read().is_some());
196    /// # })
197    /// ```
198    pub async fn read(&self) -> RwLockReadGuard<'_, T> {
199        let mut state = self.state.load(Ordering::Acquire);
200
201        loop {
202            if state & WRITER_BIT == 0 {
203                // Make sure the number of readers doesn't overflow.
204                if state > std::isize::MAX as usize {
205                    process::abort();
206                }
207
208                // If nobody is holding a write lock or attempting to acquire it, increment the
209                // number of readers.
210                match self.state.compare_exchange(
211                    state,
212                    state + ONE_READER,
213                    Ordering::AcqRel,
214                    Ordering::Acquire,
215                ) {
216                    Ok(_) => return RwLockReadGuard(self),
217                    Err(s) => state = s,
218                }
219            } else {
220                // Start listening for "no writer" events.
221                let listener = self.no_writer.listen();
222
223                // Check again if there's a writer.
224                if self.state.load(Ordering::SeqCst) & WRITER_BIT != 0 {
225                    // Wait until the writer is dropped.
226                    listener.await;
227                    // Notify the next reader waiting in line.
228                    self.no_writer.notify(1);
229                }
230
231                // Reload the state.
232                state = self.state.load(Ordering::Acquire);
233            }
234        }
235    }
236
237    /// Attempts to acquire a read lock with the possiblity to upgrade to a write lock.
238    ///
239    /// If a read lock could not be acquired at this time, then [`None`] is returned. Otherwise, a
240    /// guard is returned that releases the lock when dropped.
241    ///
242    /// Upgradable read lock reserves the right to be upgraded to a write lock, which means there
243    /// can be at most one upgradable read lock at a time.
244    ///
245    /// # Examples
246    ///
247    /// ```
248    /// # futures_lite::future::block_on(async {
249    /// use async_rwlock::{RwLock, RwLockUpgradableReadGuard};
250    ///
251    /// let lock = RwLock::new(1);
252    ///
253    /// let reader = lock.upgradable_read().await;
254    /// assert_eq!(*reader, 1);
255    /// assert_eq!(*lock.try_read().unwrap(), 1);
256    ///
257    /// let mut writer = RwLockUpgradableReadGuard::upgrade(reader).await;
258    /// *writer = 2;
259    /// # })
260    /// ```
261    pub fn try_upgradable_read(&self) -> Option<RwLockUpgradableReadGuard<'_, T>> {
262        // First try grabbing the mutex.
263        let lock = self.mutex.try_lock()?;
264
265        let mut state = self.state.load(Ordering::Acquire);
266
267        // Make sure the number of readers doesn't overflow.
268        if state > std::isize::MAX as usize {
269            process::abort();
270        }
271
272        // Increment the number of readers.
273        loop {
274            match self.state.compare_exchange(
275                state,
276                state + ONE_READER,
277                Ordering::AcqRel,
278                Ordering::Acquire,
279            ) {
280                Ok(_) => {
281                    return Some(RwLockUpgradableReadGuard {
282                        reader: RwLockReadGuard(self),
283                        reserved: lock,
284                    })
285                }
286                Err(s) => state = s,
287            }
288        }
289    }
290
291    /// Attempts to acquire a read lock with the possiblity to upgrade to a write lock.
292    ///
293    /// Returns a guard that releases the lock when dropped.
294    ///
295    /// Upgradable read lock reserves the right to be upgraded to a write lock, which means there
296    /// can be at most one upgradable read lock at a time.
297    ///
298    /// Note that attempts to acquire an upgradable read lock will block if there are concurrent
299    /// attempts to acquire another upgradable read lock or a write lock.
300    ///
301    /// # Examples
302    ///
303    /// ```
304    /// # futures_lite::future::block_on(async {
305    /// use async_rwlock::{RwLock, RwLockUpgradableReadGuard};
306    ///
307    /// let lock = RwLock::new(1);
308    ///
309    /// let reader = lock.upgradable_read().await;
310    /// assert_eq!(*reader, 1);
311    /// assert_eq!(*lock.try_read().unwrap(), 1);
312    ///
313    /// let mut writer = RwLockUpgradableReadGuard::upgrade(reader).await;
314    /// *writer = 2;
315    /// # })
316    /// ```
317    pub async fn upgradable_read(&self) -> RwLockUpgradableReadGuard<'_, T> {
318        // First grab the mutex.
319        let lock = self.mutex.lock().await;
320
321        let mut state = self.state.load(Ordering::Acquire);
322
323        // Make sure the number of readers doesn't overflow.
324        if state > std::isize::MAX as usize {
325            process::abort();
326        }
327
328        // Increment the number of readers.
329        loop {
330            match self.state.compare_exchange(
331                state,
332                state + ONE_READER,
333                Ordering::AcqRel,
334                Ordering::Acquire,
335            ) {
336                Ok(_) => {
337                    return RwLockUpgradableReadGuard {
338                        reader: RwLockReadGuard(self),
339                        reserved: lock,
340                    }
341                }
342                Err(s) => state = s,
343            }
344        }
345    }
346
347    /// Attempts to acquire a write lock.
348    ///
349    /// If a write lock could not be acquired at this time, then [`None`] is returned. Otherwise, a
350    /// guard is returned that releases the lock when dropped.
351    ///
352    /// # Examples
353    ///
354    /// ```
355    /// # futures_lite::future::block_on(async {
356    /// use async_rwlock::RwLock;
357    ///
358    /// let lock = RwLock::new(1);
359    ///
360    /// assert!(lock.try_write().is_some());
361    /// let reader = lock.read().await;
362    /// assert!(lock.try_write().is_none());
363    /// # })
364    /// ```
365    pub fn try_write(&self) -> Option<RwLockWriteGuard<'_, T>> {
366        // First try grabbing the mutex.
367        let lock = self.mutex.try_lock()?;
368
369        // If there are no readers, grab the write lock.
370        if self.state.compare_and_swap(0, WRITER_BIT, Ordering::AcqRel) == 0 {
371            Some(RwLockWriteGuard { writer: RwLockWriteGuardInner(self), reserved: lock })
372        } else {
373            None
374        }
375    }
376
377    /// Acquires a write lock.
378    ///
379    /// Returns a guard that releases the lock when dropped.
380    ///
381    /// # Examples
382    ///
383    /// ```
384    /// # futures_lite::future::block_on(async {
385    /// use async_rwlock::RwLock;
386    ///
387    /// let lock = RwLock::new(1);
388    ///
389    /// let writer = lock.write().await;
390    /// assert!(lock.try_read().is_none());
391    /// # })
392    /// ```
393    pub async fn write(&self) -> RwLockWriteGuard<'_, T> {
394        // First grab the mutex.
395        let lock = self.mutex.lock().await;
396
397        // Set `WRITER_BIT` and create a guard that unsets it in case this future is canceled.
398        self.state.fetch_or(WRITER_BIT, Ordering::SeqCst);
399        let guard = RwLockWriteGuard { writer: RwLockWriteGuardInner(self), reserved: lock };
400
401        // If there are readers, we need to wait for them to finish.
402        while self.state.load(Ordering::SeqCst) != WRITER_BIT {
403            // Start listening for "no readers" events.
404            let listener = self.no_readers.listen();
405
406            // Check again if there are readers.
407            if self.state.load(Ordering::Acquire) != WRITER_BIT {
408                // Wait for the readers to finish.
409                listener.await;
410            }
411        }
412
413        guard
414    }
415
416    /// Returns a mutable reference to the inner value.
417    ///
418    /// Since this call borrows the lock mutably, no actual locking takes place. The mutable borrow
419    /// statically guarantees no locks exist.
420    ///
421    /// # Examples
422    ///
423    /// ```
424    /// # futures_lite::future::block_on(async {
425    /// use async_rwlock::RwLock;
426    ///
427    /// let mut lock = RwLock::new(1);
428    ///
429    /// *lock.get_mut() = 2;
430    /// assert_eq!(*lock.read().await, 2);
431    /// # })
432    /// ```
433    pub fn get_mut(&mut self) -> &mut T {
434        unsafe { &mut *self.value.get() }
435    }
436}
437
438impl<T: fmt::Debug + ?Sized> fmt::Debug for RwLock<T> {
439    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
440        struct Locked;
441        impl fmt::Debug for Locked {
442            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
443                f.write_str("<locked>")
444            }
445        }
446
447        match self.try_read() {
448            None => f.debug_struct("RwLock").field("value", &Locked).finish(),
449            Some(guard) => f.debug_struct("RwLock").field("value", &&*guard).finish(),
450        }
451    }
452}
453
454impl<T> From<T> for RwLock<T> {
455    fn from(val: T) -> RwLock<T> {
456        RwLock::new(val)
457    }
458}
459
460impl<T: Default + ?Sized> Default for RwLock<T> {
461    fn default() -> RwLock<T> {
462        RwLock::new(Default::default())
463    }
464}
465
466/// A guard that releases the read lock when dropped.
467pub struct RwLockReadGuard<'a, T: ?Sized>(&'a RwLock<T>);
468
469unsafe impl<T: Sync + ?Sized> Send for RwLockReadGuard<'_, T> {}
470unsafe impl<T: Sync + ?Sized> Sync for RwLockReadGuard<'_, T> {}
471
472impl<T: ?Sized> Drop for RwLockReadGuard<'_, T> {
473    fn drop(&mut self) {
474        // Decrement the number of readers.
475        if self.0.state.fetch_sub(ONE_READER, Ordering::SeqCst) & !WRITER_BIT == ONE_READER {
476            // If this was the last reader, trigger the "no readers" event.
477            self.0.no_readers.notify(1);
478        }
479    }
480}
481
482impl<T: fmt::Debug + ?Sized> fmt::Debug for RwLockReadGuard<'_, T> {
483    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
484        fmt::Debug::fmt(&**self, f)
485    }
486}
487
488impl<T: fmt::Display + ?Sized> fmt::Display for RwLockReadGuard<'_, T> {
489    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
490        (**self).fmt(f)
491    }
492}
493
494impl<T: ?Sized> Deref for RwLockReadGuard<'_, T> {
495    type Target = T;
496
497    fn deref(&self) -> &T {
498        unsafe { &*self.0.value.get() }
499    }
500}
501
502/// A guard that releases the upgradable read lock when dropped.
503pub struct RwLockUpgradableReadGuard<'a, T: ?Sized> {
504    reader: RwLockReadGuard<'a, T>,
505    reserved: MutexGuard<'a, ()>,
506}
507
508unsafe impl<T: Send + Sync + ?Sized> Send for RwLockUpgradableReadGuard<'_, T> {}
509unsafe impl<T: Sync + ?Sized> Sync for RwLockUpgradableReadGuard<'_, T> {}
510
511impl<'a, T: ?Sized> RwLockUpgradableReadGuard<'a, T> {
512    /// Converts this guard into a writer guard.
513    fn into_writer(self) -> RwLockWriteGuard<'a, T> {
514        let writer = RwLockWriteGuard { writer: RwLockWriteGuardInner(self.reader.0), reserved: self.reserved };
515        mem::forget(self.reader);
516        writer
517    }
518
519    /// Downgrades into a regular reader guard.
520    ///
521    /// # Examples
522    ///
523    /// ```
524    /// # futures_lite::future::block_on(async {
525    /// use async_rwlock::{RwLock, RwLockUpgradableReadGuard};
526    ///
527    /// let lock = RwLock::new(1);
528    ///
529    /// let reader = lock.upgradable_read().await;
530    /// assert_eq!(*reader, 1);
531    ///
532    /// assert!(lock.try_upgradable_read().is_none());
533    ///
534    /// let reader = RwLockUpgradableReadGuard::downgrade(reader);
535    /// 
536    /// assert!(lock.try_upgradable_read().is_some());
537    /// # })
538    /// ```
539    pub fn downgrade(guard: Self) -> RwLockReadGuard<'a, T> {
540        guard.reader
541    }
542
543    /// Attempts to upgrade into a write lock.
544    ///
545    /// If a write lock could not be acquired at this time, then [`None`] is returned. Otherwise,
546    /// an upgraded guard is returned that releases the write lock when dropped.
547    ///
548    /// This function can only fail if there are other active read locks.
549    ///
550    /// # Examples
551    ///
552    /// ```
553    /// # futures_lite::future::block_on(async {
554    /// use async_rwlock::{RwLock, RwLockUpgradableReadGuard};
555    ///
556    /// let lock = RwLock::new(1);
557    ///
558    /// let reader = lock.upgradable_read().await;
559    /// assert_eq!(*reader, 1);
560    ///
561    /// let reader2 = lock.read().await;
562    /// let reader = RwLockUpgradableReadGuard::try_upgrade(reader).unwrap_err();
563    ///
564    /// drop(reader2);
565    /// let writer = RwLockUpgradableReadGuard::try_upgrade(reader).unwrap();
566    /// # })
567    /// ```
568    pub fn try_upgrade(guard: Self) -> Result<RwLockWriteGuard<'a, T>, Self> {
569        // If there are no readers, grab the write lock.
570        if guard
571            .reader
572            .0
573            .state
574            .compare_and_swap(ONE_READER, WRITER_BIT, Ordering::AcqRel)
575            == ONE_READER
576        {
577            Ok(guard.into_writer())
578        } else {
579            Err(guard)
580        }
581    }
582
583    /// Upgrades into a write lock.
584    ///
585    /// # Examples
586    ///
587    /// ```
588    /// # futures_lite::future::block_on(async {
589    /// use async_rwlock::{RwLock, RwLockUpgradableReadGuard};
590    ///
591    /// let lock = RwLock::new(1);
592    ///
593    /// let reader = lock.upgradable_read().await;
594    /// assert_eq!(*reader, 1);
595    ///
596    /// let mut writer = RwLockUpgradableReadGuard::upgrade(reader).await;
597    /// *writer = 2;
598    /// # })
599    /// ```
600    pub async fn upgrade(guard: Self) -> RwLockWriteGuard<'a, T> {
601        // Set `WRITER_BIT` and decrement the number of readers at the same time.
602        guard
603            .reader
604            .0
605            .state
606            .fetch_sub(ONE_READER - WRITER_BIT, Ordering::SeqCst);
607
608        // Convert into a write guard that unsets `WRITER_BIT` in case this future is canceled.
609        let guard = guard.into_writer();
610
611        // If there are readers, we need to wait for them to finish.
612        while guard.writer.0.state.load(Ordering::SeqCst) != WRITER_BIT {
613            // Start listening for "no readers" events.
614            let listener = guard.writer.0.no_readers.listen();
615
616            // Check again if there are readers.
617            if guard.writer.0.state.load(Ordering::Acquire) != WRITER_BIT {
618                // Wait for the readers to finish.
619                listener.await;
620            }
621        }
622
623        guard
624    }
625}
626
627impl<T: fmt::Debug + ?Sized> fmt::Debug for RwLockUpgradableReadGuard<'_, T> {
628    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
629        fmt::Debug::fmt(&**self, f)
630    }
631}
632
633impl<T: fmt::Display + ?Sized> fmt::Display for RwLockUpgradableReadGuard<'_, T> {
634    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
635        (**self).fmt(f)
636    }
637}
638
639impl<T: ?Sized> Deref for RwLockUpgradableReadGuard<'_, T> {
640    type Target = T;
641
642    fn deref(&self) -> &T {
643        unsafe { &*self.reader.0.value.get() }
644    }
645}
646
647struct RwLockWriteGuardInner<'a, T: ?Sized>(&'a RwLock<T>);
648
649impl<T: ?Sized> Drop for RwLockWriteGuardInner<'_, T> {
650    fn drop(&mut self) {
651        // Unset `WRITER_BIT`.
652        self.0.state.fetch_and(!WRITER_BIT, Ordering::SeqCst);
653        // Trigger the "no writer" event.
654        self.0.no_writer.notify(1);
655    }
656}
657
658/// A guard that releases the write lock when dropped.
659pub struct RwLockWriteGuard<'a, T: ?Sized> {
660    writer: RwLockWriteGuardInner<'a, T>,
661    reserved: MutexGuard<'a, ()>,
662}
663
664unsafe impl<T: Send + ?Sized> Send for RwLockWriteGuard<'_, T> {}
665unsafe impl<T: Sync + ?Sized> Sync for RwLockWriteGuard<'_, T> {}
666
667impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
668    /// Downgrades into a regular reader guard.
669    ///
670    /// # Examples
671    ///
672    /// ```
673    /// # futures_lite::future::block_on(async {
674    /// use async_rwlock::{RwLock, RwLockWriteGuard};
675    ///
676    /// let lock = RwLock::new(1);
677    ///
678    /// let mut writer = lock.write().await;
679    /// *writer += 1;
680    ///
681    /// assert!(lock.try_read().is_none());
682    ///
683    /// let reader = RwLockWriteGuard::downgrade(writer);
684    /// assert_eq!(*reader, 2);
685    /// 
686    /// assert!(lock.try_read().is_some());
687    /// # })
688    /// ```
689    pub fn downgrade(guard: Self) -> RwLockReadGuard<'a, T> {
690        // Atomically downgrade state.
691        guard.writer.0.state.fetch_add(ONE_READER - WRITER_BIT, Ordering::SeqCst);
692
693        // Trigger the "no writer" event.
694        guard.writer.0.no_writer.notify(1);
695
696        // Convert into a read guard and return.
697        let new_guard = RwLockReadGuard(guard.writer.0);
698        mem::forget(guard.writer); // `RwLockWriteGuardInner::drop()` should not be called!
699        new_guard
700    }
701
702    /// Downgrades into an upgradable reader guard.
703    ///
704    /// # Examples
705    ///
706    /// ```
707    /// # futures_lite::future::block_on(async {
708    /// use async_rwlock::{RwLock, RwLockUpgradableReadGuard, RwLockWriteGuard};
709    ///
710    /// let lock = RwLock::new(1);
711    ///
712    /// let mut writer = lock.write().await;
713    /// *writer += 1;
714    ///
715    /// assert!(lock.try_read().is_none());
716    ///
717    /// let reader = RwLockWriteGuard::downgrade_to_upgradable(writer);
718    /// assert_eq!(*reader, 2);
719    /// 
720    /// assert!(lock.try_write().is_none());
721    /// assert!(lock.try_read().is_some());
722    ///
723    /// assert!(RwLockUpgradableReadGuard::try_upgrade(reader).is_ok())
724    /// # })
725    /// ```
726    pub fn downgrade_to_upgradable(guard: Self) -> RwLockUpgradableReadGuard<'a, T> {
727        // Atomically downgrade state.
728        guard.writer.0.state.fetch_add(ONE_READER - WRITER_BIT, Ordering::SeqCst);
729
730        // Convert into an upgradable read guard and return.
731        let new_guard = RwLockUpgradableReadGuard {
732            reader: RwLockReadGuard(guard.writer.0),
733            reserved: guard.reserved,
734        };
735        mem::forget(guard.writer); // `RwLockWriteGuardInner::drop()` should not be called!
736        new_guard
737    }
738}
739
740impl<T: fmt::Debug + ?Sized> fmt::Debug for RwLockWriteGuard<'_, T> {
741    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
742        fmt::Debug::fmt(&**self, f)
743    }
744}
745
746impl<T: fmt::Display + ?Sized> fmt::Display for RwLockWriteGuard<'_, T> {
747    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
748        (**self).fmt(f)
749    }
750}
751
752impl<T: ?Sized> Deref for RwLockWriteGuard<'_, T> {
753    type Target = T;
754
755    fn deref(&self) -> &T {
756        unsafe { &*self.writer.0.value.get() }
757    }
758}
759
760impl<T: ?Sized> DerefMut for RwLockWriteGuard<'_, T> {
761    fn deref_mut(&mut self) -> &mut T {
762        unsafe { &mut *self.writer.0.value.get() }
763    }
764}