Add `CondVar::wait_{timeout_,}while` to `debug_sync`
[rust-lightning] / lightning / src / sync / nostd_sync.rs
1 pub use ::alloc::sync::Arc;
2 use core::ops::{Deref, DerefMut};
3 use core::time::Duration;
4 use core::cell::{RefCell, Ref, RefMut};
5 use super::{LockTestExt, LockHeldState};
6
7 pub type LockResult<Guard> = Result<Guard, ()>;
8
9 pub struct Condvar {}
10
11 pub struct WaitTimeoutResult(bool);
12 impl WaitTimeoutResult {
13         pub fn timed_out(&self) -> bool { self.0 }
14 }
15
16 impl Condvar {
17         pub fn new() -> Condvar {
18                 Condvar { }
19         }
20
21         pub fn wait<'a, T>(&'a self, guard: MutexGuard<'a, T>) -> LockResult<MutexGuard<'a, T>> {
22                 Ok(guard)
23         }
24
25         #[allow(unused)]
26         pub fn wait_timeout<'a, T>(&'a self, guard: MutexGuard<'a, T>, _dur: Duration) -> LockResult<(MutexGuard<'a, T>, ())> {
27                 Ok((guard, ()))
28         }
29
30         pub fn wait_while<'a, T, F: FnMut(&mut T) -> bool>(&'a self, mut guard: MutexGuard<'a, T>, mut condition: F)
31         -> LockResult<MutexGuard<'a, T>> {
32                 assert!(!condition(&mut *guard));
33                 Ok(guard)
34         }
35
36         #[allow(unused)]
37         pub fn wait_timeout_while<'a, T, F: FnMut(&mut T) -> bool>(&'a self, mut guard: MutexGuard<'a, T>, dur: Duration, mut condition: F)
38         -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)> {
39                 if condition(&mut *guard) {
40                         Ok((guard, WaitTimeoutResult(true)))
41                 } else {
42                         Ok((guard, WaitTimeoutResult(false)))
43                 }
44         }
45
46         pub fn notify_all(&self) {}
47 }
48
49 pub struct Mutex<T: ?Sized> {
50         inner: RefCell<T>
51 }
52
53 #[must_use = "if unused the Mutex will immediately unlock"]
54 pub struct MutexGuard<'a, T: ?Sized + 'a> {
55         lock: RefMut<'a, T>,
56 }
57
58 impl<T: ?Sized> Deref for MutexGuard<'_, T> {
59         type Target = T;
60
61         fn deref(&self) -> &T {
62                 &self.lock.deref()
63         }
64 }
65
66 impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
67         fn deref_mut(&mut self) -> &mut T {
68                 self.lock.deref_mut()
69         }
70 }
71
72 impl<T> Mutex<T> {
73         pub fn new(inner: T) -> Mutex<T> {
74                 Mutex { inner: RefCell::new(inner) }
75         }
76
77         pub fn lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>> {
78                 Ok(MutexGuard { lock: self.inner.borrow_mut() })
79         }
80
81         pub fn try_lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>> {
82                 Ok(MutexGuard { lock: self.inner.borrow_mut() })
83         }
84
85         pub fn into_inner(self) -> LockResult<T> {
86                 Ok(self.inner.into_inner())
87         }
88 }
89
90 impl<'a, T: 'a> LockTestExt<'a> for Mutex<T> {
91         #[inline]
92         fn held_by_thread(&self) -> LockHeldState {
93                 if self.lock().is_err() { return LockHeldState::HeldByThread; }
94                 else { return LockHeldState::NotHeldByThread; }
95         }
96         type ExclLock = MutexGuard<'a, T>;
97         #[inline]
98         fn unsafe_well_ordered_double_lock_self(&'a self) -> MutexGuard<T> { self.lock().unwrap() }
99 }
100
101 pub struct RwLock<T: ?Sized> {
102         inner: RefCell<T>
103 }
104
105 pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
106         lock: Ref<'a, T>,
107 }
108
109 pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
110         lock: RefMut<'a, T>,
111 }
112
113 impl<T: ?Sized> Deref for RwLockReadGuard<'_, T> {
114         type Target = T;
115
116         fn deref(&self) -> &T {
117                 &self.lock.deref()
118         }
119 }
120
121 impl<T: ?Sized> Deref for RwLockWriteGuard<'_, T> {
122         type Target = T;
123
124         fn deref(&self) -> &T {
125                 &self.lock.deref()
126         }
127 }
128
129 impl<T: ?Sized> DerefMut for RwLockWriteGuard<'_, T> {
130         fn deref_mut(&mut self) -> &mut T {
131                 self.lock.deref_mut()
132         }
133 }
134
135 impl<T> RwLock<T> {
136         pub fn new(inner: T) -> RwLock<T> {
137                 RwLock { inner: RefCell::new(inner) }
138         }
139
140         pub fn read<'a>(&'a self) -> LockResult<RwLockReadGuard<'a, T>> {
141                 Ok(RwLockReadGuard { lock: self.inner.borrow() })
142         }
143
144         pub fn write<'a>(&'a self) -> LockResult<RwLockWriteGuard<'a, T>> {
145                 Ok(RwLockWriteGuard { lock: self.inner.borrow_mut() })
146         }
147
148         pub fn try_write<'a>(&'a self) -> LockResult<RwLockWriteGuard<'a, T>> {
149                 match self.inner.try_borrow_mut() {
150                         Ok(lock) => Ok(RwLockWriteGuard { lock }),
151                         Err(_) => Err(())
152                 }
153         }
154 }
155
156 impl<'a, T: 'a> LockTestExt<'a> for RwLock<T> {
157         #[inline]
158         fn held_by_thread(&self) -> LockHeldState {
159                 if self.write().is_err() { return LockHeldState::HeldByThread; }
160                 else { return LockHeldState::NotHeldByThread; }
161         }
162         type ExclLock = RwLockWriteGuard<'a, T>;
163         #[inline]
164         fn unsafe_well_ordered_double_lock_self(&'a self) -> RwLockWriteGuard<T> { self.write().unwrap() }
165 }
166
167 pub type FairRwLock<T> = RwLock<T>;