conc_util/event/
onceevent.rs1use 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}