abs_sync/
async_lock.rs

1use core::{
2    ops::{Deref, DerefMut, Try},
3    pin::Pin,
4};
5
6use crate::cancellation::TrMayCancel;
7
8/// Reader-Writer lock for asynchronous task pattern.
9pub trait TrAsyncRwLock {
10    type Target: ?Sized;
11
12    fn acquire(&self) -> impl TrAcquire<'_, Self::Target>;
13}
14
15pub trait TrAcquire<'a, T>
16where
17    Self: 'a,
18    T: 'a + ?Sized,
19{
20    type ReaderGuard<'g>: TrReaderGuard<'a, 'g, T> where 'a: 'g;
21
22    type WriterGuard<'g>: TrWriterGuard<'a, 'g, T> where 'a: 'g;
23
24    type UpgradableGuard<'g>: TrUpgradableReaderGuard<'a, 'g, T> where 'a: 'g;
25
26    fn try_read<'g>(
27        self: Pin<&'g mut Self>,
28    ) -> impl Try<Output = Self::ReaderGuard<'g>>
29    where
30        'a: 'g;
31
32    fn try_write<'g>(
33        self: Pin<&'g mut Self>,
34    ) -> impl Try<Output = Self::WriterGuard<'g>>
35    where
36        'a: 'g;
37
38    fn try_upgradable_read<'g>(
39        self: Pin<&'g mut Self>,
40    ) -> impl Try<Output = Self::UpgradableGuard<'g>>
41    where
42        'a: 'g;
43
44    fn read_async<'g>(
45        self: Pin<&'g mut Self>,
46    ) -> impl TrMayCancel<'g,
47        MayCancelOutput: Try<Output = Self::ReaderGuard<'g>>>
48    where
49        'a: 'g;
50
51    fn write_async<'g>(
52        self: Pin<&'g mut Self>,
53    ) -> impl TrMayCancel<'g,
54        MayCancelOutput: Try<Output = Self::WriterGuard<'g>>>
55    where
56        'a: 'g;
57
58    fn upgradable_read_async<'g>(
59        self: Pin<&'g mut Self>,
60    ) -> impl TrMayCancel<'g,
61        MayCancelOutput: Try<Output = Self::UpgradableGuard<'g>>>
62    where
63        'a: 'g;
64}
65
66pub trait TrReaderGuard<'a, 'g, T>
67where
68    'a: 'g,
69    Self: 'g + Sized + Deref<Target = T>,
70    T: 'a + ?Sized,
71{
72    type Acquire: TrAcquire<'a, T>;
73
74    fn as_reader_guard(&self) -> &Self {
75        self
76    }
77}
78
79pub trait TrUpgradableReaderGuard<'a, 'g, T>
80where
81    'a: 'g,
82    Self: 'g + TrReaderGuard<'a, 'g, T>,
83    T: 'a + ?Sized,
84{
85    fn downgrade(self) -> <Self::Acquire as TrAcquire<'a, T>>::ReaderGuard<'g>;
86
87    fn upgrade(self) -> impl TrUpgrade<'a, 'g, T, Acquire = Self::Acquire>;
88}
89
90pub trait TrWriterGuard<'a, 'g, T>
91where
92    'a: 'g,
93    Self: 'g + TrReaderGuard<'a, 'g, T> + DerefMut<Target = T>,
94    T: 'a + ?Sized,
95{
96    fn downgrade(self) -> <Self::Acquire as TrAcquire<'a, T>>::ReaderGuard<'g>;
97
98    fn downgrade_to_upgradable(
99        self,
100    ) -> <Self::Acquire as TrAcquire<'a, T>>::UpgradableGuard<'g>;
101}
102
103pub trait TrUpgrade<'a, 'g, T>
104where
105    'a: 'g,
106    T: 'a + ?Sized,
107{
108    type Acquire: TrAcquire<'a, T>;
109
110    fn try_upgrade<'u>(
111        self: Pin<&'u mut Self>,
112    ) -> impl Try<Output = <Self::Acquire as TrAcquire<'a, T>>::WriterGuard<'u>>
113    where
114        'g: 'u;
115
116    fn upgrade_async<'u>(
117        self: Pin<&'u mut Self>,
118    ) -> impl TrMayCancel<'u, MayCancelOutput: Try<Output =
119        <Self::Acquire as TrAcquire<'a, T>>::WriterGuard<'u>>>
120    where
121        'g: 'u;
122
123    fn into_guard(
124        self,
125    ) -> <Self::Acquire as TrAcquire<'a, T>>::UpgradableGuard<'g>;
126}
127
128#[cfg(test)]
129mod demo_ {
130    use std::{
131        borrow::BorrowMut,
132        ops::{ControlFlow, Deref, DerefMut},
133    };
134    use pin_utils::pin_mut;
135
136    use crate::cancellation::{NonCancellableToken, TrMayCancel};
137
138    use super::*;
139
140    #[allow(dead_code)]
141    async fn generic_rwlock_smoke_<B, L, T>(rwlock: B)
142    where
143        B: BorrowMut<L>,
144        L: TrAsyncRwLock<Target = T>,
145    {
146        let acq = rwlock.borrow().acquire();
147        pin_mut!(acq);
148        let read_async = acq.as_mut().read_async();
149        // let write_async = acq.write_async(); // illegal
150        let ControlFlow::Continue(read_guard) = read_async
151            .may_cancel_with(NonCancellableToken::pinned())
152            .await
153            .branch()
154        else {
155            panic!()
156        };
157        let _ = read_guard.deref();
158        // let write_async = acq.write_async(); // illegal
159        drop(read_guard);
160        let ControlFlow::Continue(upgradable) = acq
161            .as_mut()
162            .upgradable_read_async()
163            .may_cancel_with(NonCancellableToken::pinned())
164            .await
165            .branch()
166        else {
167            panic!()
168        };
169        let _ = upgradable.deref();
170        let upgrade = upgradable.upgrade();
171        pin_mut!(upgrade);
172        let ControlFlow::Continue(mut write_guard) = upgrade
173            .upgrade_async()
174            .may_cancel_with(NonCancellableToken::pinned())
175            .await
176            .branch()
177        else {
178            panic!()
179        };
180        let _ = write_guard.deref_mut();
181        let upgradable = write_guard.downgrade_to_upgradable();
182        drop(upgradable)
183    }
184}