use std::io;
use std::os::windows::io::{AsRawHandle, RawHandle};
use std::process::Child;
use windows_sys::Win32::Foundation::{HANDLE, WAIT_OBJECT_0, WAIT_TIMEOUT};
use windows_sys::Win32::System::Threading::{WaitForSingleObject, INFINITE};
#[derive(Copy, Clone)]
pub struct Handle(RawHandle);
pub fn get_handle(child: &Child) -> Handle {
Handle(child.as_raw_handle())
}
pub fn wait_noreap(handle: Handle) -> io::Result<()> {
let wait_ret = unsafe { WaitForSingleObject(handle.0 as HANDLE, INFINITE) };
match wait_ret {
WAIT_OBJECT_0 => Ok(()),
_ => Err(io::Error::last_os_error()),
}
}
pub fn try_wait_noreap(handle: Handle) -> io::Result<bool> {
let wait_ret = unsafe { WaitForSingleObject(handle.0 as HANDLE, 0) };
if wait_ret == WAIT_OBJECT_0 {
Ok(true)
} else if wait_ret == WAIT_TIMEOUT {
Ok(false)
} else {
Err(io::Error::last_os_error())
}
}
#[cfg(feature = "timeout")]
pub fn wait_deadline_noreap(handle: Handle, deadline: std::time::Instant) -> io::Result<bool> {
let timeout = deadline.saturating_duration_since(std::time::Instant::now());
let timeout_ms = (timeout.as_nanos().saturating_add(999_999) / 1_000_000)
.try_into()
.unwrap_or(u32::MAX);
let wait_ret = unsafe { WaitForSingleObject(handle.0 as HANDLE, timeout_ms) };
use windows_sys::Win32::Foundation::WAIT_TIMEOUT;
match wait_ret {
WAIT_OBJECT_0 => Ok(true),
WAIT_TIMEOUT => Ok(false),
_ => Err(io::Error::last_os_error()),
}
}