conc_util/event/
onceevent.rs1use core::{
2 mem::ManuallyDrop,
3 pin::Pin,
4 task::{self, Waker},
5};
6
7use alloc::vec::Vec;
8
9use crate::{event::Event, sync::{OnceFlag, SpinLock}};
10
11#[derive(Debug)]
12pub struct OnceEvent {
13 used: OnceFlag,
14 wakers: SpinLock<ManuallyDrop<Vec<Waker>>>,
15}
16
17impl OnceEvent {
18 pub fn new() -> Self {
19 Self {
20 used: OnceFlag::new(),
21 wakers: SpinLock::new(ManuallyDrop::new(Vec::new())),
22 }
23 }
24}
25
26impl Future for &OnceEvent {
27 type Output = ();
28
29 fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
30 if self.used.fired() {
31 return task::Poll::Ready(());
32 }
33
34 let mut wakers = self.wakers.lock();
35
36 if self.used.fired() {
37 return task::Poll::Ready(());
38 }
39
40 wakers.push(cx.waker().clone());
41 return task::Poll::Pending;
42 }
43}
44
45impl Event for OnceEvent {
46 type Wait<'a> = &'a Self;
47
48 fn fire(&self) {
49 if self.used.fire() {
50 return;
51 }
52
53 let mut lock = self.wakers.lock();
54 let wakers = unsafe { ManuallyDrop::take(&mut lock) };
58 drop(lock);
59
60 for waker in wakers {
61 waker.wake();
62 }
63 }
64
65 fn wait<'a>(&'a self) -> Self::Wait<'a> {
66 self
67 }
68}
69
70impl Drop for OnceEvent {
71 fn drop(&mut self) {
72 if !self.used.fired_mut() {
73 unsafe { ManuallyDrop::drop(self.wakers.get()) };
76 }
77 }
78}