sync_wait_object/
windows.rs

1///! Windows implementation of `ManualResetEvent` and `AutoResetEvent` which directly wraps over Win32 API.
2
3use std::{
4    time::Duration,
5    ops::{ Deref, DerefMut }
6};
7use windows::Win32::{
8    Foundation::{ HANDLE, CloseHandle, GetLastError, WAIT_OBJECT_0, WAIT_TIMEOUT, WAIT_FAILED, WIN32_ERROR },
9    System::Threading::{ CreateEventA, WaitForSingleObject, ResetEvent, SetEvent },
10    System::WindowsProgramming::INFINITE
11};
12use crate::{ WaitObjectError, Result, SignalWaitable };
13
14// --------------------------------------- DATA STRUCTURE ---------------------------------------------
15#[derive(Clone)]
16pub struct WaitEvent(HANDLE);
17
18/// Wrapper of [`WaitEvent`] of type `bool`, which focuses on waiting for `true` without resetting.
19///
20/// *Examples*
21/// The example does not make sense (as [`sync_wait_object::WaitEvent`] of `u8` makes more sense for this scenario), it is just for demonstration.
22///
23/// ```rust
24/// # use sync_wait_object::windows::ManualResetEvent;
25/// use std::{ thread, sync::Arc, sync::atomic::{ AtomicU8, Ordering } };
26/// use sync_wait_object::SignalWaitable;
27///
28/// let ev = ManualResetEvent::new();
29/// let mut signal = ev.clone();
30/// let v = Arc::new(AtomicU8::new(0));
31/// let v_setter = v.clone();
32///
33/// thread::spawn(move || {
34///     v_setter.store(1, Ordering::SeqCst);
35///     signal.set().unwrap();
36/// });
37///
38/// ev.wait_until_set().unwrap();
39/// assert_eq!(v.load(Ordering::SeqCst), 1);
40///
41/// ```
42#[derive(Clone)]
43pub struct ManualResetEvent(WaitEvent);
44
45/// Wrapper of [`WaitEvent`] of type `bool`, which focuses on waiting for `true` with automatic reset to `false`.
46///
47/// *Examples*
48///
49/// ```rust
50/// # use sync_wait_object::windows::AutoResetEvent;
51/// use std::{ thread, sync::Arc, sync::atomic::{ AtomicU8, Ordering } };
52/// use sync_wait_object::SignalWaitable;
53///
54/// let ev = AutoResetEvent::new();
55/// let mut signal = ev.clone();
56///
57/// let mut next = AutoResetEvent::new();
58/// let wait_next = next.clone();
59///
60/// let v = Arc::new(AtomicU8::new(0));
61/// let v_setter = v.clone();
62///
63/// thread::spawn(move || {
64///     v_setter.store(1, Ordering::SeqCst);
65///     signal.set().unwrap();
66///
67///     wait_next.wait_until_set().unwrap();
68///
69///     v_setter.store(2, Ordering::SeqCst);
70///     signal.set().unwrap();
71/// });
72///
73/// ev.wait_until_set().unwrap();
74/// assert_eq!(v.load(Ordering::SeqCst), 1);
75///
76/// next.set().unwrap();
77///
78/// ev.wait_until_set().unwrap();
79/// assert_eq!(v.load(Ordering::SeqCst), 2);
80/// ```
81#[derive(Clone)]
82pub struct AutoResetEvent(WaitEvent);
83
84// ---------------------------------------- FUNCTIONS -------------------------------------------------
85#[inline]
86pub(crate) fn get_win32_last_error() -> WIN32_ERROR {
87    unsafe { GetLastError() }
88}
89
90#[inline]
91pub(crate) fn get_last_error() -> WaitObjectError {
92    get_win32_last_error().into()
93}
94
95pub(crate) fn to_result(ret: bool) -> Result<()> {
96    if ret { Ok(()) }
97    else { Err(get_last_error()) }
98}
99
100pub trait HandleWrapper {
101    fn handle(&self) -> HANDLE;
102}
103
104// ---------------------------------------- IMPLEMENTATIONS -------------------------------------------
105impl From<WIN32_ERROR> for WaitObjectError {
106    fn from(value: WIN32_ERROR) -> Self {
107        WaitObjectError::OsError(value.0 as isize, value.to_hresult().message().to_string())
108    }
109}
110
111impl WaitEvent {
112    fn native_wait(&self, timeout: u32) -> Result<()> {
113        let ret = unsafe { WaitForSingleObject(self.0, timeout) };
114        match ret {
115            WAIT_OBJECT_0 => Ok(()),
116            WAIT_TIMEOUT => Err(WaitObjectError::Timeout),
117            WAIT_FAILED => Err(get_last_error()),
118            _ => unreachable!()
119        }
120    }
121}
122
123impl HandleWrapper for WaitEvent {
124    #[inline]
125    fn handle(&self) -> HANDLE { self.0 }
126}
127
128impl SignalWaitable for WaitEvent {
129    #[inline]
130    fn wait_until_set(&self) -> Result<()> {
131        self.native_wait(INFINITE)
132    }
133
134    #[inline] fn wait(&self, timeout: Duration) -> Result<()> {
135        self.native_wait(timeout.as_millis() as u32)
136    }
137
138    fn set(&mut self) -> Result<()> {
139        to_result(unsafe { SetEvent(self.0).as_bool() })
140    }
141    fn reset(&mut self) -> Result<()> {
142        to_result(unsafe { ResetEvent(self.0).as_bool() })
143    }
144}
145
146impl Drop for WaitEvent {
147    fn drop(&mut self) {
148        if !self.0.is_invalid() {
149            unsafe { CloseHandle(self.0); }
150            self.0 = HANDLE::default();
151        }
152    }
153}
154
155impl ManualResetEvent {
156    #[inline]
157    pub fn new() -> Self { Self::new_init(false) }
158
159    pub fn new_init(initial_state: bool) -> Self {
160        let handle = unsafe { CreateEventA(None, true, initial_state, None).unwrap() };
161        Self(WaitEvent(handle))
162    }
163}
164
165impl Deref for ManualResetEvent {
166    type Target = WaitEvent;
167
168    fn deref(&self) -> &Self::Target {
169        &self.0
170    }
171}
172
173impl DerefMut for ManualResetEvent {
174    fn deref_mut(&mut self) -> &mut Self::Target {
175        &mut self.0
176    }
177}
178
179impl AutoResetEvent {
180    #[inline]
181    pub fn new() -> Self { Self::new_init(false) }
182
183    pub fn new_init(initial_state: bool) -> Self {
184        let handle = unsafe { CreateEventA(None, false, initial_state, None).unwrap() };
185        Self(WaitEvent(handle))
186    }
187}
188
189impl Deref for AutoResetEvent {
190    type Target = WaitEvent;
191
192    fn deref(&self) -> &Self::Target {
193        &self.0
194    }
195}
196
197impl DerefMut for AutoResetEvent {
198    fn deref_mut(&mut self) -> &mut Self::Target {
199        &mut self.0
200    }
201}
202
203#[cfg(test)]
204mod test {
205}