1use std::cell::{Cell, RefCell};
5use std::collections::VecDeque;
6use std::future::Future;
7use std::pin::Pin;
8use std::rc::Rc;
9use std::task::{Context, Poll, Waker};
10
11struct EventInner {
16 is_set: Cell<bool>,
17 waiters: RefCell<Vec<Waker>>,
18}
19
20#[derive(Clone)]
22pub struct Event {
23 inner: Rc<EventInner>,
24}
25
26impl Event {
27 #[allow(clippy::new_without_default)]
28 pub fn new() -> Event {
29 Event {
30 inner: Rc::new(EventInner {
31 is_set: Cell::new(false),
32 waiters: RefCell::new(Vec::new()),
33 }),
34 }
35 }
36
37 pub fn set(&self) {
38 self.inner.is_set.set(true);
39 for w in self.inner.waiters.borrow_mut().drain(..) {
40 w.wake();
41 }
42 }
43
44 pub fn clear(&self) {
45 self.inner.is_set.set(false);
46 }
47
48 pub fn is_set(&self) -> bool {
49 self.inner.is_set.get()
50 }
51
52 pub fn wait(&self) -> EventWait {
53 EventWait {
54 inner: self.inner.clone(),
55 }
56 }
57}
58
59pub struct EventWait {
60 inner: Rc<EventInner>,
61}
62
63impl Future for EventWait {
64 type Output = ();
65 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
66 if self.inner.is_set.get() {
67 Poll::Ready(())
68 } else {
69 self.inner.waiters.borrow_mut().push(cx.waker().clone());
70 Poll::Pending
71 }
72 }
73}
74
75struct LockWaiter {
80 granted: Cell<bool>,
81 waker: RefCell<Option<Waker>>,
82}
83
84struct LockInner {
85 locked: Cell<bool>,
86 waiters: RefCell<VecDeque<Rc<LockWaiter>>>,
87}
88
89impl LockInner {
90 fn release(&self) {
92 match self.waiters.borrow_mut().pop_front() {
93 Some(w) => {
94 w.granted.set(true);
95 if let Some(waker) = w.waker.borrow_mut().take() {
96 waker.wake();
97 }
98 }
100 None => {
101 self.locked.set(false);
102 }
103 }
104 }
105}
106
107#[derive(Clone)]
108pub struct Lock {
109 inner: Rc<LockInner>,
110}
111
112impl Lock {
113 #[allow(clippy::new_without_default)]
114 pub fn new() -> Lock {
115 Lock {
116 inner: Rc::new(LockInner {
117 locked: Cell::new(false),
118 waiters: RefCell::new(VecDeque::new()),
119 }),
120 }
121 }
122
123 pub fn locked(&self) -> bool {
124 self.inner.locked.get()
125 }
126
127 pub fn acquire(&self) -> Acquire {
128 Acquire {
129 inner: self.inner.clone(),
130 waiter: None,
131 acquired: false,
132 }
133 }
134}
135
136pub struct Acquire {
137 inner: Rc<LockInner>,
138 waiter: Option<Rc<LockWaiter>>,
139 acquired: bool,
140}
141
142impl Future for Acquire {
143 type Output = LockGuard;
144 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<LockGuard> {
145 match &self.waiter {
146 None => {
147 if !self.inner.locked.get() {
148 self.inner.locked.set(true);
149 self.acquired = true;
150 Poll::Ready(LockGuard {
151 inner: self.inner.clone(),
152 })
153 } else {
154 let w = Rc::new(LockWaiter {
155 granted: Cell::new(false),
156 waker: RefCell::new(Some(cx.waker().clone())),
157 });
158 self.inner.waiters.borrow_mut().push_back(w.clone());
159 self.waiter = Some(w);
160 Poll::Pending
161 }
162 }
163 Some(w) => {
164 if w.granted.get() {
165 self.acquired = true;
166 Poll::Ready(LockGuard {
167 inner: self.inner.clone(),
168 })
169 } else {
170 *w.waker.borrow_mut() = Some(cx.waker().clone());
171 Poll::Pending
172 }
173 }
174 }
175 }
176}
177
178impl Drop for Acquire {
179 fn drop(&mut self) {
180 if self.acquired {
181 return; }
183 if let Some(w) = &self.waiter {
184 if w.granted.get() {
185 self.inner.release();
187 } else {
188 self.inner
190 .waiters
191 .borrow_mut()
192 .retain(|x| !Rc::ptr_eq(x, w));
193 }
194 }
195 }
196}
197
198pub struct LockGuard {
200 inner: Rc<LockInner>,
201}
202
203impl Drop for LockGuard {
204 fn drop(&mut self) {
205 self.inner.release();
206 }
207}
208
209#[cfg(test)]
214mod tests {
215 use super::*;
216 use crate::executor;
217 use crate::testing::{assert_pending, block_on};
218 use std::cell::RefCell;
219 use std::rc::Rc;
220
221 #[test]
222 fn wait_before_set_wakes() {
223 block_on(async {
224 let ev = Event::new();
225 let setter = ev.clone();
226 executor::spawn(async move {
227 setter.set();
228 });
229 ev.wait().await; });
231 }
232
233 #[test]
239 fn set_latches_until_cleared() {
240 block_on(async {
241 let ev = Event::new();
242 ev.set();
243 ev.wait().await; assert!(ev.is_set());
245 });
246 }
247
248 #[test]
249 fn clear_makes_a_later_wait_block_again() {
250 let ev = Event::new();
251 ev.set();
252 ev.clear();
253 assert!(!ev.is_set());
254 assert_pending(async move { ev.wait().await });
255 }
256
257 #[test]
258 fn one_set_wakes_every_waiter() {
259 block_on(async {
260 let ev = Event::new();
261 let woken = Rc::new(RefCell::new(0));
262 for _ in 0..3 {
263 let (e, w) = (ev.clone(), woken.clone());
264 executor::spawn(async move {
265 e.wait().await;
266 *w.borrow_mut() += 1;
267 });
268 }
269 crate::executor::current().run_until_idle();
271 ev.set();
272 crate::executor::current().run_until_idle();
273 assert_eq!(*woken.borrow(), 3, "all three saw one set");
274 });
275 }
276
277 #[test]
278 fn lock_is_fifo_fair() {
279 block_on(async {
280 let lock = Lock::new();
281 let order = Rc::new(RefCell::new(Vec::new()));
282
283 let held = lock.acquire().await; for who in 1..=3 {
286 let (l, o) = (lock.clone(), order.clone());
287 executor::spawn(async move {
288 let _g = l.acquire().await;
289 o.borrow_mut().push(who);
290 });
291 crate::executor::current().run_until_idle();
293 }
294
295 drop(held);
296 crate::executor::current().run_until_idle();
297 assert_eq!(*order.borrow(), vec![1, 2, 3], "granted in request order");
298 });
299 }
300}