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 Event for OnceEvent {
27 fn fire(&self) {
28 if self.used.fire() {
29 return;
30 }
31
32 let mut lock = self.wakers.lock();
33 let wakers = unsafe { ManuallyDrop::take(&mut lock) };
37 drop(lock);
38
39 for waker in wakers {
40 waker.wake();
41 }
42 }
43}
44
45impl Drop for OnceEvent {
46 fn drop(&mut self) {
47 if !self.used.fired_mut() {
48 unsafe { ManuallyDrop::drop(self.wakers.get()) };
51 }
52 }
53}
54
55impl Future for &OnceEvent {
56 type Output = ();
57
58 fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll<Self::Output> {
59 if self.used.fired() {
60 return task::Poll::Ready(());
61 }
62
63 let mut wakers = self.wakers.lock();
64
65 if self.used.fired() {
66 return task::Poll::Ready(());
67 }
68
69 wakers.push(cx.waker().clone());
70 return task::Poll::Pending;
71 }
72}