| 1 | use super::*; |
| 2 | |
| 3 | pub struct Waiter(HANDLE); |
| 4 | pub struct WaiterSignaler(HANDLE); |
| 5 | unsafe impl Send for WaiterSignaler {} |
| 6 | |
| 7 | impl Waiter { |
| 8 | pub fn new() -> crate::Result<(Waiter, WaiterSignaler)> { |
| 9 | unsafe { |
| 10 | let handle: *mut c_void = CreateEventW(lpeventattributes:core::ptr::null(), bmanualreset:1, binitialstate:0, lpname: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 | |
| 20 | impl 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 | |
| 34 | impl Drop for Waiter { |
| 35 | fn drop(&mut self) { |
| 36 | unsafe { |
| 37 | WaitForSingleObject(self.0, dwmilliseconds:0xFFFFFFFF); |
| 38 | CloseHandle(self.0); |
| 39 | } |
| 40 | } |
| 41 | } |
| 42 | |