use std::{
io,
os::windows::io::{
AsHandle, AsRawHandle, BorrowedHandle, IntoRawHandle, OwnedHandle, RawHandle,
},
sync::Arc,
};
use windows_sys::Win32::{
Foundation::{CloseHandle, HANDLE},
System::Threading::{CreateEventW, ResetEvent, SetEvent},
};
use crate::notify::Notify;
#[derive(Debug)]
struct Handle(HANDLE);
unsafe impl Send for Handle {}
unsafe impl Sync for Handle {}
impl Drop for Handle {
fn drop(&mut self) {
unsafe {
CloseHandle(self.0);
}
}
}
#[derive(Clone, Debug)]
pub struct Ring(Arc<Handle>);
#[derive(Clone, Debug)]
pub struct Event(Arc<Handle>);
pub fn event() -> io::Result<(Ring, Event)> {
let handle = unsafe { CreateEventW(core::ptr::null(), 1, 0, core::ptr::null()) };
if handle.is_null() {
return Err(io::Error::last_os_error());
}
let handle = Arc::new(Handle(handle));
Ok((Ring(handle.clone()), Event(handle)))
}
impl Notify for Ring {
type Error = io::Error;
fn notify(&self) -> Result<(), Self::Error> {
if unsafe { SetEvent(self.0.0) } == 0 {
Err(io::Error::last_os_error())
} else {
Ok(())
}
}
}
impl Ring {
pub fn from_owned_handle(handle: OwnedHandle) -> Self {
Self(Arc::new(Handle(handle.into_raw_handle().cast())))
}
}
impl Event {
pub fn from_owned_handle(handle: OwnedHandle) -> Self {
Self(Arc::new(Handle(handle.into_raw_handle().cast())))
}
pub(crate) fn clear(&self) -> io::Result<()> {
if unsafe { ResetEvent(self.0.0) } == 0 {
Err(io::Error::last_os_error())
} else {
Ok(())
}
}
pub(crate) fn handle(&self) -> HANDLE {
self.0.0
}
}
impl AsRawHandle for Event {
fn as_raw_handle(&self) -> RawHandle {
self.0.0.cast()
}
}
impl AsRawHandle for Ring {
fn as_raw_handle(&self) -> RawHandle {
self.0.0.cast()
}
}
impl AsHandle for Event {
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}
impl AsHandle for Ring {
fn as_handle(&self) -> BorrowedHandle<'_> {
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
}
}