lock_ordering/lock/rwlock.rs
1/// Locking implementation for [crate::ReadWrite].
2///
3/// Describes how to acquire access to the state for a [crate::LockLevel]
4/// implementation with [Method](crate::LockLevel::Method) = `ReadWrite`.
5/// The error and RAII guard types are implementation-defined.
6pub trait RwLock {
7 /// Error that could be produced when acquiring read access.
8 ///
9 /// For implementations where acquiring a lock is an infallible operation,
10 /// the error type [`core::convert::Infallible`] can be used.
11 type ReadError<'a>
12 where
13 Self: 'a;
14
15 /// Error that could be produced when acquiring write access.
16 ///
17 /// For implementations where acquiring a lock is an infallible operation,
18 /// the error type [`core::convert::Infallible`] can be used.
19 type WriteError<'a>
20 where
21 Self: 'a;
22
23 /// [RAII guard] for shared access to data protected by the lock.
24 ///
25 /// [RAII guard]: https://doc.rust-lang.org/rust-by-example/scope/raii.html
26 type ReadGuard<'a>
27 where
28 Self: 'a;
29
30 /// [RAII guard] for exclusive access to data protected by the lock.
31 ///
32 /// [RAII guard]: https://doc.rust-lang.org/rust-by-example/scope/raii.html
33 type WriteGuard<'a>
34 where
35 Self: 'a;
36
37 /// Attempts to acquire shared access to data.
38 ///
39 /// Returns an RAII guard that provides shared (read) access to the data, or
40 /// an error on failure.
41 fn read(&self) -> Result<Self::ReadGuard<'_>, Self::ReadError<'_>>;
42
43 /// Attempts to acquire exclusive access to data.
44 ///
45 /// Returns an RAII guard that provides exclusive (read/write) access to the
46 /// data, or an error on failure.
47 fn write(&self) -> Result<Self::WriteGuard<'_>, Self::WriteError<'_>>;
48}
49
50#[cfg(feature = "std")]
51mod std {
52 //! Implementation of [`RwLock`] for [`std::sync::RwLock`].
53 use std::sync::{PoisonError, RwLock, RwLockReadGuard, RwLockWriteGuard};
54
55 impl<T: ?Sized> super::RwLock for RwLock<T> {
56 type ReadError<'a> = PoisonError<RwLockReadGuard<'a, T>> where Self: 'a ;
57 type WriteError<'a> = PoisonError<RwLockWriteGuard<'a, T>> where Self: 'a;
58
59 type ReadGuard<'a> = RwLockReadGuard<'a, T> where Self: 'a ;
60 type WriteGuard<'a> = RwLockWriteGuard<'a, T> where Self: 'a;
61
62 fn read(&self) -> Result<Self::ReadGuard<'_>, Self::ReadError<'_>> {
63 RwLock::read(self)
64 }
65
66 fn write(&self) -> Result<Self::WriteGuard<'_>, Self::WriteError<'_>> {
67 RwLock::write(self)
68 }
69 }
70}
71
72/// Async locking implementation for [crate::ReadWrite].
73///
74/// Describes how to acquire access to the state for a [crate::LockLevel]
75/// implementation with [Method](crate::LockLevel::Method) = `ReadWrite`.
76/// The error and RAII guard types are implementation-defined.
77#[cfg(feature = "async")]
78pub trait AsyncRwLock {
79 /// [RAII guard] for shared access to data protected by the lock.
80 ///
81 /// [RAII guard]: https://doc.rust-lang.org/rust-by-example/scope/raii.html
82 type ReadGuard<'a>
83 where
84 Self: 'a;
85
86 /// [RAII guard] for exclusive access to data protected by the lock.
87 ///
88 /// [RAII guard]: https://doc.rust-lang.org/rust-by-example/scope/raii.html
89 type WriteGuard<'a>
90 where
91 Self: 'a;
92
93 /// Acquires shared access to data.
94 ///
95 /// Locks the data in `self` for shared (read) access, yielding the current
96 /// task until the lock has been acquired.
97 fn read(&self) -> impl core::future::Future<Output = Self::ReadGuard<'_>>;
98
99 /// Acquires exclusive access to data.
100 ///
101 /// Locks the data in `self` for exclusive (read/write) access, yielding the
102 /// current task until the lock has been acquired.
103 fn write(&self) -> impl core::future::Future<Output = Self::WriteGuard<'_>>;
104}
105
106#[cfg(feature = "tokio")]
107mod tokio {
108 use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
109
110 impl<T: ?Sized> super::AsyncRwLock for RwLock<T> {
111 type ReadGuard<'a> = RwLockReadGuard<'a, T> where Self: 'a ;
112
113 type WriteGuard<'a> = RwLockWriteGuard<'a, T> where Self: 'a;
114
115 async fn read(&self) -> Self::ReadGuard<'_> {
116 RwLock::read(self).await
117 }
118
119 async fn write(&self) -> Self::WriteGuard<'_> {
120 RwLock::write(self).await
121 }
122 }
123}