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 crate::duplicate::{Access, duplicate_handle_with_access};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ResetMode {
Auto,
Manual,
}
#[derive(Debug)]
pub struct Event {
handle: OwnedHandle,
}
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 })
}
#[must_use]
pub unsafe fn from_owned_handle(handle: OwnedHandle) -> Self {
Self { 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_clone(&self) -> io::Result<Self> {
Ok(Self {
handle: self.handle.try_clone()?,
})
}
pub fn try_clone_wait_only(&self) -> io::Result<WaitOnlyEvent> {
Ok(WaitOnlyEvent {
handle: duplicate_handle_with_access(self, Access::SYNCHRONIZE)?,
})
}
}
#[derive(Debug)]
pub struct WaitOnlyEvent {
handle: OwnedHandle,
}
impl WaitOnlyEvent {
pub fn try_clone(&self) -> io::Result<Self> {
Ok(Self {
handle: self.handle.try_clone()?,
})
}
}
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 OwnedHandle {
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 OwnedHandle {
fn from(event: Event) -> Self {
event.handle
}
}
#[cfg(test)]
mod tests;