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 | |