Skip to main content

conc_util/event/
onceevent.rs

1use core::{pin::Pin, task::{self, Waker}};
2
3use alloc::{sync::Arc, vec::Vec};
4
5use crate::sync::{OnceFlag, SpinLock};
6
7struct OnceInner {
8    used: OnceFlag,
9    wakers: SpinLock<Vec<Waker>>,
10}
11
12#[derive(Clone)]
13pub struct OnceEvent(Arc<OnceInner>);
14
15impl OnceEvent {
16    pub fn new() -> Self {
17        Self(Arc::new(OnceInner {
18            used: OnceFlag::new(),
19            wakers: SpinLock::new(Vec::new()),
20        }))
21    }
22
23    pub fn fire(&self) {
24        let mut wakers = self.0.wakers.lock();
25
26        if self.0.used.fire() {
27            return;
28        }
29
30        let wakers = core::mem::replace(&mut *wakers, Vec::new());
31        for waker in wakers {
32            waker.wake();
33        }
34    }
35}
36
37impl Future for OnceEvent {
38    type Output = ();
39
40    fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
41        let mut wakers = self.0.wakers.lock();
42
43        if self.0.used.fired() {
44            return task::Poll::Ready(());
45        }
46
47        wakers.push(cx.waker().clone());
48        return task::Poll::Pending;
49    }
50}