pal_event/
windows.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#![cfg(windows)]
5
6use crate::Event;
7use std::os::windows::prelude::*;
8use windows_sys::Win32::Foundation;
9use windows_sys::Win32::System::Threading;
10
11pub type Inner = OwnedHandle;
12
13impl Clone for Event {
14    fn clone(&self) -> Self {
15        Self(
16            self.0
17                .try_clone()
18                .expect("out of resources cloning wait object"),
19        )
20    }
21}
22
23impl Event {
24    pub(crate) fn new_inner() -> std::io::Result<Self> {
25        // SAFETY: passing valid parameters as documented.
26        let handle = unsafe {
27            let handle = Threading::CreateEventW(
28                std::ptr::null_mut(),
29                false.into(),
30                false.into(),
31                std::ptr::null(),
32            ) as RawHandle;
33            if handle.is_null() {
34                return Err(std::io::Error::last_os_error());
35            }
36            OwnedHandle::from_raw_handle(handle)
37        };
38        Ok(Self(handle))
39    }
40
41    pub(crate) fn signal_inner(&self) {
42        // SAFETY: passing a valid handle.
43        let r = unsafe { Threading::SetEvent(self.0.as_raw_handle()) };
44        if r == 0 {
45            // This can only fail due to an invalid handle, which can only
46            // happen due to some bug in unsafe code.
47            panic!("signal failed: {}", std::io::Error::last_os_error());
48        }
49    }
50
51    pub(crate) fn wait_inner(&self) {
52        // SAFETY: passing a valid handle.
53        let r =
54            unsafe { Threading::WaitForSingleObject(self.0.as_raw_handle(), Threading::INFINITE) };
55        if r != Foundation::WAIT_OBJECT_0 {
56            // This can only fail due to an invalid handle, which can only
57            // happen due to some bug in unsafe code.
58            panic!("wait failed: {}", std::io::Error::last_os_error());
59        }
60    }
61
62    pub(crate) fn try_wait_inner(&self) -> bool {
63        // SAFETY: passing a valid handle.
64        let r = unsafe { Threading::WaitForSingleObject(self.0.as_raw_handle(), 0) };
65        match r {
66            Foundation::WAIT_OBJECT_0 => true,
67            Foundation::WAIT_TIMEOUT => false,
68            r => {
69                // This can only fail due to an invalid handle, which can only
70                // happen due to some bug in unsafe code.
71                panic!("wait failed ({r:#x}): {}", std::io::Error::last_os_error());
72            }
73        }
74    }
75}
76
77impl From<OwnedHandle> for Event {
78    fn from(handle: OwnedHandle) -> Self {
79        Self(handle)
80    }
81}
82
83impl AsHandle for Event {
84    fn as_handle(&self) -> BorrowedHandle<'_> {
85        self.0.as_handle()
86    }
87}
88
89impl From<Event> for OwnedHandle {
90    fn from(event: Event) -> OwnedHandle {
91        event.0
92    }
93}
94
95#[cfg(feature = "mesh")]
96mesh_protobuf::os_resource!(Event, OwnedHandle);