use std::{io, pin::Pin, task::Poll};
use compio_driver::{NotifyHandle, OpCode, PushEntry};
use windows_sys::Win32::System::IO::OVERLAPPED;
use crate::{key::Key, runtime::op::OpFuture, Runtime};
#[derive(Debug)]
pub struct Event {
user_data: Key<NopPending>,
}
impl Event {
pub fn new() -> io::Result<Self> {
let user_data = Runtime::current().inner().submit_raw(NopPending::new());
let user_data = match user_data {
PushEntry::Pending(user_data) => user_data,
PushEntry::Ready(_) => unreachable!("NopPending always returns Pending"),
};
Ok(Self { user_data })
}
pub fn handle(&self) -> io::Result<EventHandle> {
EventHandle::new(&self.user_data)
}
pub async fn wait(self) -> io::Result<()> {
let future = OpFuture::new(self.user_data);
future.await.0?;
Ok(())
}
}
pub struct EventHandle {
handle: NotifyHandle,
}
impl EventHandle {
fn new(user_data: &Key<NopPending>) -> io::Result<Self> {
let runtime = Runtime::current();
Ok(Self {
handle: unsafe { runtime.inner().handle_for(**user_data)? },
})
}
pub fn notify(self) -> io::Result<()> {
self.handle.notify()
}
}
#[derive(Debug)]
struct NopPending {}
impl NopPending {
pub fn new() -> Self {
Self {}
}
}
impl OpCode for NopPending {
unsafe fn operate(self: Pin<&mut Self>, _optr: *mut OVERLAPPED) -> Poll<io::Result<usize>> {
Poll::Pending
}
unsafe fn cancel(self: Pin<&mut Self>, _optr: *mut OVERLAPPED) -> io::Result<()> {
Ok(())
}
}