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}