use std::sync::Arc;
use windows::Win32::Foundation::{CloseHandle, HANDLE};
use windows::Win32::System::IO::CancelIoEx;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) struct RawHandle(isize);
impl RawHandle {
pub(crate) fn from_handle(handle: HANDLE) -> Self {
Self(handle.0 as isize)
}
pub(crate) fn as_handle(self) -> HANDLE {
HANDLE(self.0 as *mut core::ffi::c_void)
}
}
pub(crate) struct PipeHandle(RawHandle);
impl PipeHandle {
pub(crate) fn new(handle: HANDLE) -> Arc<Self> {
Arc::new(Self(RawHandle::from_handle(handle)))
}
pub(crate) fn as_handle(&self) -> HANDLE {
self.0.as_handle()
}
pub(crate) fn cancel(&self) {
_ = unsafe { CancelIoEx(self.as_handle(), None) };
}
}
impl Drop for PipeHandle {
fn drop(&mut self) {
let handle = self.as_handle();
if handle.is_invalid() {
return;
}
_ = unsafe { CloseHandle(handle) };
}
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
#[test]
fn round_trips_a_handle_value() {
let handle = HANDLE(0x1234 as *mut core::ffi::c_void);
assert_eq!(RawHandle::from_handle(handle).as_handle(), handle);
}
}