use std::{
io,
marker::PhantomData,
task::{Context, Poll},
};
use windows_sys::{
Win32::{
Foundation::{FALSE, TRUE},
System::Console::{CTRL_BREAK_EVENT, CTRL_C_EVENT, SetConsoleCtrlHandler},
},
core::BOOL,
};
use super::{Set, Signal, lock, wake};
use crate::{Mode, Runtime, scheduler::dispose};
pub(super) struct Watch<M>(PhantomData<M::Ptr<()>>)
where
M: Mode;
impl<M> Watch<M>
where
M: Mode,
{
pub(super) fn new(_runtime: &Runtime<M>) -> io::Result<Self> {
Ok(Self(PhantomData))
}
pub(super) fn poll_deliver(&self, _cx: &mut Context<'_>) -> Poll<io::Result<()>> {
Poll::Pending
}
}
pub(super) fn arrived() -> Set {
Set::EMPTY
}
pub(super) struct Handlers {
added: bool,
}
impl Handlers {
pub(super) const fn new() -> Self {
Self { added: false }
}
pub(super) fn take(&mut self, _signal: Signal) -> io::Result<()> {
if self.added {
return Ok(());
}
if unsafe { SetConsoleCtrlHandler(Some(handle), TRUE) } == FALSE {
return Err(io::Error::last_os_error());
}
self.added = true;
Ok(())
}
pub(super) fn give_back(&mut self, _signal: Signal) {}
}
pub(crate) extern "system" fn handle(event: u32) -> BOOL {
let signal = match event {
CTRL_C_EVENT => Signal::Interrupt,
CTRL_BREAK_EVENT => Signal::Break,
_ => return FALSE,
};
let delivered = lock().deliver(signal.into());
let Some(woken) = delivered else {
return FALSE;
};
if let Some(panic) = wake(woken) {
dispose(panic);
}
TRUE
}