async_lock/
rwlock.rs

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