use std::io;
use std::os::windows::io::{
AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, OwnedHandle, RawHandle,
};
use std::ptr;
use windows_sys::Win32::Foundation::{FALSE, TRUE};
use windows_sys::Win32::System::Threading::{CreateEventW, ResetEvent, SetEvent};
use win_handles_sys::{Access, duplicate_handle_with_access};
use win_shared_os_owned_handle::SharedHandle;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ResetMode {
Auto,
Manual,
}
#[derive(Clone, Debug)]
pub struct Event {
handle: SharedHandle,
}
impl Event {
pub fn new(reset: ResetMode, initially_signalled: bool) -> io::Result<Self> {
let manual_reset = match reset {
ResetMode::Auto => FALSE,
ResetMode::Manual => TRUE,
};
let initial_state = if initially_signalled { TRUE } else { FALSE };
let raw = unsafe { CreateEventW(ptr::null(), manual_reset, initial_state, ptr::null()) };
if raw.is_null() {
return Err(io::Error::last_os_error());
}
let handle = unsafe { OwnedHandle::from_raw_handle(raw) };
Ok(Self {
handle: SharedHandle::new(handle),
})
}
#[must_use]
pub unsafe fn from_owned_handle(handle: OwnedHandle) -> Self {
Self {
handle: SharedHandle::new(handle),
}
}
pub fn set(&self) -> io::Result<()> {
if unsafe { SetEvent(self.handle.as_raw_handle()) } == FALSE {
return Err(io::Error::last_os_error());
}
Ok(())
}
pub fn reset(&self) -> io::Result<()> {
if unsafe { ResetEvent(self.handle.as_raw_handle()) } == FALSE {
return Err(io::Error::last_os_error());
}
Ok(())
}
pub fn try_into_owned(self) -> Result<OwnedHandle, Self> {
self.handle
.try_into_owned()
.map_err(|handle| Self { handle })
}
pub fn duplicate_wait_only(&self) -> io::Result<WaitOnlyEvent> {
Ok(WaitOnlyEvent {
handle: SharedHandle::new(duplicate_handle_with_access(self, Access::SYNCHRONIZE)?),
})
}
}
#[derive(Clone, Debug)]
pub struct WaitOnlyEvent {
handle: SharedHandle,
}
impl WaitOnlyEvent {
pub fn try_into_owned(self) -> Result<OwnedHandle, Self> {
self.handle
.try_into_owned()
.map_err(|handle| Self { handle })
}
}
impl AsHandle for WaitOnlyEvent {
fn as_handle(&self) -> BorrowedHandle<'_> {
self.handle.as_handle()
}
}
impl AsRawHandle for WaitOnlyEvent {
fn as_raw_handle(&self) -> RawHandle {
self.handle.as_raw_handle()
}
}
impl From<WaitOnlyEvent> for SharedHandle {
fn from(event: WaitOnlyEvent) -> Self {
event.handle
}
}
impl AsHandle for Event {
fn as_handle(&self) -> BorrowedHandle<'_> {
self.handle.as_handle()
}
}
impl AsRawHandle for Event {
fn as_raw_handle(&self) -> RawHandle {
self.handle.as_raw_handle()
}
}
impl From<Event> for SharedHandle {
fn from(event: Event) -> Self {
event.handle
}
}
#[cfg(test)]
mod tests;