use crate::*;
use winapi::shared::winerror::*;
use winapi::um::processthreadsapi::*;
use winapi::um::synchapi::WaitForSingleObject;
use winapi::um::winbase::*;
pub fn get_current_thread() -> thread::PsuedoHandle<'static> { unsafe { thread::PsuedoHandle::from_raw(GetCurrentThread()).unwrap() } }
pub fn get_current_thread_id() -> thread::Id { unsafe { GetCurrentThreadId() } }
pub fn resume_thread(thread: &thread::OwnedHandle) -> Result<u32, Error> { let r = unsafe { ResumeThread(thread.as_handle()) }; if r as i32 != -1 { Ok(r) } else { Err(Error::get_last()) } }
pub fn suspend_thread(thread: &thread::OwnedHandle) -> Result<u32, Error> { let r = unsafe { SuspendThread(thread.as_handle()) }; if r as i32 != -1 { Ok(r) } else { Err(Error::get_last()) } }
pub fn get_exit_code_thread<'a>(thread: impl AsRef<thread::Handle<'a>>) -> Result<u32, Error> {
let mut exit_code = 0;
Error::get_last_if(0 == unsafe { GetExitCodeThread(thread.as_ref().as_handle(), &mut exit_code) })?;
Ok(exit_code)
}
pub fn is_thread_running<'a>(thread: impl AsRef<thread::Handle<'a>>) -> bool {
WAIT_TIMEOUT == unsafe { WaitForSingleObject(thread.as_ref().as_handle(), 0) }
}
pub fn wait_for_thread<'a>(thread: impl AsRef<thread::Handle<'a>>) -> Result<u32, Error> {
match unsafe { WaitForSingleObject(thread.as_ref().as_handle(), INFINITE) } {
WAIT_OBJECT_0 => {},
WAIT_ABANDONED_0 => return Err(Error(ERROR_ABANDONED_WAIT_0)), WAIT_TIMEOUT => return Err(Error(ERROR_ABANDONED_WAIT_63)), WAIT_FAILED => return Err(Error::get_last()),
_ => return Err(Error(ERROR_ABANDONED_WAIT_63)), }
get_exit_code_thread(thread)
}
pub fn exit_thread(exit_code: u32) { unsafe { ExitThread(exit_code) } }
#[cfg(std)] #[test] fn test_wait_exit() {
use winapi::um::minwinbase::STILL_ACTIVE;
use std::thread::*;
let child = spawn(|| { sleep(core::time::Duration::from_millis(500)); exit_thread(3); });
let child = thread::OwnedHandle::from(child);
assert!(is_thread_running(&child));
assert_eq!(STILL_ACTIVE, get_exit_code_thread(&child).unwrap());
assert_eq!(3, wait_for_thread(&child).unwrap());
assert!(!is_thread_running(&child));
assert_eq!(3, get_exit_code_thread(&child).unwrap());
}