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}