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}