1use std::{
10 pin::Pin,
11 sync::atomic::Ordering::Relaxed,
12 task::{Context, Poll},
13};
14
15use oneapi_rs_sys::{event::ffi, types::SharedWaker};
16
17use pin_project::pin_project;
18
19use crate::{info::InfoTarget, private::Sealed, queue::Queue};
20
21pub struct Event(pub(crate) cxx::UniquePtr<ffi::Event>);
22
23impl Event {
24 pub fn wait(&mut self) {
25 ffi::wait(&mut self.0);
26 }
27}
28
29impl Sealed for Event {}
30impl InfoTarget for Event {}
31
32impl From<cxx::UniquePtr<ffi::Event>> for Event {
33 fn from(value: cxx::UniquePtr<ffi::Event>) -> Self {
34 Self(value)
35 }
36}
37
38impl Clone for Event {
39 fn clone(&self) -> Self {
40 ffi::clone(&self.0).into()
41 }
42}
43
44#[pin_project]
45pub struct EventFuture {
46 event: Event,
47 shared: SharedWaker,
48 set_callback: bool,
49 queue: Option<Queue>,
50}
51
52impl Future for EventFuture {
53 type Output = ();
54
55 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
56 let this = self.project();
57
58 if *this.set_callback == false {
60 *this.set_callback = true;
61 let mut queue = Queue::new_immediate();
62 this.shared.waker.register(cx.waker());
63 unsafe { ffi::register_callback(&mut queue.0, &this.event.0, this.shared) };
66 this.queue.replace(queue);
67 } else {
68 if this.shared.done.load(Relaxed) {
70 return Poll::Ready(());
71 }
72
73 this.shared.waker.register(cx.waker());
74 }
75
76 if this.shared.done.load(Relaxed) {
79 Poll::Ready(())
80 } else {
81 Poll::Pending
82 }
83 }
84}
85
86impl IntoFuture for Event {
87 type Output = ();
88 type IntoFuture = EventFuture;
89
90 fn into_future(self) -> Self::IntoFuture {
91 EventFuture {
92 event: self,
93 shared: SharedWaker::new(),
94 set_callback: false,
95 queue: None,
96 }
97 }
98}