1 | use super::*; |
2 | |
3 | #[doc (hidden)] |
4 | pub struct Waiter(isize); |
5 | pub struct WaiterSignaler(isize); |
6 | |
7 | impl Waiter { |
8 | pub fn new() -> crate::Result<(Waiter, WaiterSignaler)> { |
9 | unsafe { |
10 | let handle: isize = CreateEventW(lpeventattributes:std::ptr::null(), bmanualreset:1, binitialstate:0, lpname:std::ptr::null()); |
11 | if handle == 0 { |
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 | SetEvent(self.0); |
29 | } |
30 | } |
31 | |
32 | impl Drop for Waiter { |
33 | fn drop(&mut self) { |
34 | unsafe { |
35 | WaitForSingleObject(self.0, dwmilliseconds:0xFFFFFFFF); |
36 | CloseHandle(self.0); |
37 | } |
38 | } |
39 | } |
40 | |