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