windows_future/
waiter.rs

1use super::*;
2
3pub struct Waiter(HANDLE);
4pub struct WaiterSignaler(HANDLE);
5unsafe impl Send for WaiterSignaler {}
6
7impl Waiter {
8    pub fn new() -> crate::Result<(Waiter, WaiterSignaler)> {
9        unsafe {
10            let handle = CreateEventW(core::ptr::null(), 1, 0, core::ptr::null());
11            if handle.is_null() {
12                Err(crate::Error::from_win32())
13            } else {
14                Ok((Waiter(handle), WaiterSignaler(handle)))
15            }
16        }
17    }
18}
19
20impl WaiterSignaler {
21    /// # Safety
22    /// Signals the `Waiter`. This is unsafe because the lifetime of `WaiterSignaler` is not tied
23    /// to the lifetime of the `Waiter`. This is not possible in this case because the `Waiter`
24    /// is used to signal a WinRT async completion and the compiler doesn't know that the lifetime
25    /// of the delegate is bounded by the calling function.
26    pub unsafe fn signal(&self) {
27        // https://github.com/microsoft/windows-rs/pull/374#discussion_r535313344
28        unsafe {
29            SetEvent(self.0);
30        }
31    }
32}
33
34impl Drop for Waiter {
35    fn drop(&mut self) {
36        unsafe {
37            WaitForSingleObject(self.0, 0xFFFFFFFF);
38            CloseHandle(self.0);
39        }
40    }
41}