1use std::{
10 pin::Pin,
11 sync::{Arc, atomic::Ordering::Relaxed},
12 task::{Context, Poll},
13};
14
15use sycl_rs_sys::{event::ffi, types::SharedWaker};
16
17use pin_project::pin_project;
18
19use crate::{Result, 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) -> Result<()> {
29 ffi::wait(&mut self.0)
30 }
31}
32
33impl Sealed for Event {}
34impl InfoTarget for Event {}
35
36impl From<cxx::UniquePtr<ffi::Event>> for Event {
37 fn from(value: cxx::UniquePtr<ffi::Event>) -> Self {
38 Self(value)
39 }
40}
41
42impl Clone for Event {
43 fn clone(&self) -> Self {
44 ffi::clone(&self.0).into()
45 }
46}
47
48#[pin_project]
49pub struct EventFuture {
50 event: Event,
51 shared: Arc<SharedWaker>,
52 set_callback: bool,
53 queue: Option<Queue>,
54}
55
56impl Future for EventFuture {
57 type Output = Result<()>;
58
59 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
60 let this = self.project();
61
62 if *this.set_callback == false {
64 *this.set_callback = true;
65 let mut queue = Queue::new_immediate();
66 this.shared.waker.register(cx.waker());
67
68 let ptr = Arc::into_raw(this.shared.clone());
71 let result = unsafe { ffi::register_callback(&mut queue.0, &this.event.0, ptr) };
72 match result {
73 Ok(_) => {
74 this.queue.replace(queue);
75 }
76 Err(_) => {
77 return Poll::Ready(result);
78 }
79 }
80 } else {
81 if this.shared.done.load(Relaxed) {
83 return Poll::Ready(this.event.wait());
85 }
86
87 this.shared.waker.register(cx.waker());
88 }
89
90 if this.shared.done.load(Relaxed) {
93 Poll::Ready(this.event.wait())
95 } else {
96 Poll::Pending
97 }
98 }
99}
100
101impl IntoFuture for Event {
102 type Output = Result<()>;
103 type IntoFuture = EventFuture;
104
105 fn into_future(self) -> Self::IntoFuture {
106 EventFuture {
107 event: self,
108 shared: Arc::new(SharedWaker::new()),
109 set_callback: false,
110 queue: None,
111 }
112 }
113}