async_rwlock/
lib.rs

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