xref: /aosp_15_r20/external/crosvm/base/src/sys/windows/event.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2022 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use std::ffi::CString;
6 use std::mem::MaybeUninit;
7 use std::os::windows::io::AsRawHandle;
8 use std::os::windows::io::RawHandle;
9 use std::ptr::null;
10 use std::time::Duration;
11 
12 use serde::Deserialize;
13 use serde::Serialize;
14 use win_util::SecurityAttributes;
15 use win_util::SelfRelativeSecurityDescriptor;
16 use winapi::shared::minwindef::DWORD;
17 use winapi::shared::minwindef::FALSE;
18 use winapi::shared::minwindef::TRUE;
19 use winapi::shared::winerror::WAIT_TIMEOUT;
20 use winapi::um::handleapi::DuplicateHandle;
21 use winapi::um::processthreadsapi::GetCurrentProcess;
22 use winapi::um::synchapi::CreateEventA;
23 use winapi::um::synchapi::OpenEventA;
24 use winapi::um::synchapi::ResetEvent;
25 use winapi::um::synchapi::SetEvent;
26 use winapi::um::synchapi::WaitForSingleObject;
27 use winapi::um::winbase::INFINITE;
28 use winapi::um::winbase::WAIT_FAILED;
29 use winapi::um::winbase::WAIT_OBJECT_0;
30 use winapi::um::winnt::DUPLICATE_SAME_ACCESS;
31 use winapi::um::winnt::EVENT_MODIFY_STATE;
32 use winapi::um::winnt::HANDLE;
33 
34 use super::errno_result;
35 use super::Error;
36 use super::RawDescriptor;
37 use super::Result;
38 use crate::descriptor::AsRawDescriptor;
39 use crate::descriptor::FromRawDescriptor;
40 use crate::descriptor::IntoRawDescriptor;
41 use crate::descriptor::SafeDescriptor;
42 use crate::Event;
43 use crate::EventWaitResult;
44 
45 /// A safe wrapper around Windows synchapi methods used to mimic Linux eventfd (man 2 eventfd).
46 /// Since the eventfd isn't using "EFD_SEMAPHORE", we don't need to keep count so we can just use
47 /// events.
48 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
49 #[serde(transparent)]
50 pub(crate) struct PlatformEvent {
51     event_handle: SafeDescriptor,
52 }
53 
54 pub trait EventExt {
new_auto_reset() -> Result<Event>55     fn new_auto_reset() -> Result<Event>;
open(name: &str) -> Result<Event>56     fn open(name: &str) -> Result<Event>;
create_event_with_name(name: &str) -> Result<Event>57     fn create_event_with_name(name: &str) -> Result<Event>;
58 }
59 
60 impl EventExt for Event {
new_auto_reset() -> Result<Event>61     fn new_auto_reset() -> Result<Event> {
62         PlatformEvent::new_with_manual_reset(false).map(Event)
63     }
64 
open(name: &str) -> Result<Event>65     fn open(name: &str) -> Result<Event> {
66         PlatformEvent::open(name).map(Event)
67     }
68 
create_event_with_name(name: &str) -> Result<Event>69     fn create_event_with_name(name: &str) -> Result<Event> {
70         PlatformEvent::create_event_with_name(name).map(Event)
71     }
72 }
73 
74 impl PlatformEvent {
new_with_manual_reset(manual_reset: bool) -> Result<PlatformEvent>75     pub fn new_with_manual_reset(manual_reset: bool) -> Result<PlatformEvent> {
76         // SAFETY: Safe because return value is checked.
77         let handle = unsafe {
78             CreateEventA(
79                 SecurityAttributes::new_with_security_descriptor(
80                     SelfRelativeSecurityDescriptor::get_singleton(),
81                     /* inherit= */ false,
82                 )
83                 .as_mut(),
84                 if manual_reset { TRUE } else { FALSE },
85                 FALSE, // initial state = unsignalled
86                 null(),
87             )
88         };
89         if handle.is_null() {
90             return errno_result();
91         }
92         Ok(PlatformEvent {
93             event_handle:
94             // SAFETY: Safe because the descriptor is valid.
95             unsafe { SafeDescriptor::from_raw_descriptor(handle) },
96         })
97     }
98 
create_event_with_name(name: &str) -> Result<PlatformEvent>99     pub fn create_event_with_name(name: &str) -> Result<PlatformEvent> {
100         let event_str = CString::new(String::from(name)).unwrap();
101         // SAFETY: Safe because return value is checked.
102         let handle = unsafe {
103             CreateEventA(
104                 SecurityAttributes::new_with_security_descriptor(
105                     SelfRelativeSecurityDescriptor::get_singleton(),
106                     /* inherit= */ false,
107                 )
108                 .as_mut(),
109                 FALSE, // manual_reset = false
110                 FALSE, // initial state = unsignalled
111                 event_str.as_ptr(),
112             )
113         };
114         if handle.is_null() {
115             return errno_result();
116         }
117         Ok(PlatformEvent {
118             event_handle:
119             // SAFETY: Safe because the descriptor is valid.
120             unsafe { SafeDescriptor::from_raw_descriptor(handle) },
121         })
122     }
123 
new() -> Result<PlatformEvent>124     pub fn new() -> Result<PlatformEvent> {
125         // Require manual reset
126         PlatformEvent::new_with_manual_reset(true)
127     }
128 
open(name: &str) -> Result<PlatformEvent>129     pub fn open(name: &str) -> Result<PlatformEvent> {
130         let event_str = CString::new(String::from(name)).unwrap();
131         // SAFETY: Safe because return value is checked.
132         let handle = unsafe { OpenEventA(EVENT_MODIFY_STATE, FALSE, event_str.as_ptr()) };
133         if handle.is_null() {
134             return errno_result();
135         }
136         Ok(PlatformEvent {
137             event_handle:
138             // SAFETY: Safe because the descriptor is valid.
139             unsafe { SafeDescriptor::from_raw_descriptor(handle) },
140         })
141     }
142 
143     /// See `Event::signal`.
signal(&self) -> Result<()>144     pub fn signal(&self) -> Result<()> {
145         // SAFETY: Safe because the descriptor is valid.
146         let event_result = unsafe { SetEvent(self.event_handle.as_raw_descriptor()) };
147         if event_result == 0 {
148             return errno_result();
149         }
150         Ok(())
151     }
152 
reset(&self) -> Result<()>153     pub fn reset(&self) -> Result<()> {
154         // SAFETY: Safe because the descriptor is valid.
155         let res = unsafe { ResetEvent(self.event_handle.as_raw_descriptor()) };
156         if res == 0 {
157             errno_result()
158         } else {
159             Ok(())
160         }
161     }
162 
163     /// Wait for the event with an optional timeout and reset the event if it was signaled.
wait_and_reset(&self, timeout: Option<Duration>) -> Result<EventWaitResult>164     fn wait_and_reset(&self, timeout: Option<Duration>) -> Result<EventWaitResult> {
165         let milliseconds = match timeout {
166             Some(timeout) => timeout.as_millis() as DWORD,
167             None => INFINITE,
168         };
169 
170         // SAFETY:
171         // Safe because we pass an event object handle owned by this PlatformEvent.
172         let wait_result = match unsafe {
173             WaitForSingleObject(self.event_handle.as_raw_descriptor(), milliseconds)
174         } {
175             WAIT_OBJECT_0 => Ok(EventWaitResult::Signaled),
176             WAIT_TIMEOUT => Ok(EventWaitResult::TimedOut),
177             WAIT_FAILED => errno_result(),
178             other => Err(Error::new(other)),
179         }?;
180 
181         if wait_result == EventWaitResult::Signaled {
182             self.reset()?;
183         }
184 
185         Ok(wait_result)
186     }
187 
188     /// See `Event::wait`.
wait(&self) -> Result<()>189     pub fn wait(&self) -> Result<()> {
190         let wait_result = self.wait_and_reset(None)?;
191         // Waiting with `INFINITE` can only return when the event is signaled or an error occurs.
192         // `EventWaitResult::TimedOut` is not valid here.
193         assert_eq!(wait_result, EventWaitResult::Signaled);
194         Ok(())
195     }
196 
197     /// See `Event::wait_timeout`.
wait_timeout(&self, timeout: Duration) -> Result<EventWaitResult>198     pub fn wait_timeout(&self, timeout: Duration) -> Result<EventWaitResult> {
199         self.wait_and_reset(Some(timeout))
200     }
201 
try_clone(&self) -> Result<PlatformEvent>202     pub fn try_clone(&self) -> Result<PlatformEvent> {
203         let mut event_clone: HANDLE = MaybeUninit::uninit().as_mut_ptr();
204         // SAFETY: Safe because return value is checked.
205         let duplicate_result = unsafe {
206             DuplicateHandle(
207                 GetCurrentProcess(),
208                 self.event_handle.as_raw_descriptor(),
209                 GetCurrentProcess(),
210                 &mut event_clone,
211                 0,
212                 0,
213                 DUPLICATE_SAME_ACCESS,
214             )
215         };
216         if duplicate_result == 0 {
217             return errno_result();
218         }
219         Ok(
220             // SAFETY: Safe because the descriptor is valid.
221             unsafe { PlatformEvent::from_raw_descriptor(event_clone) },
222         )
223     }
224 }
225 
226 impl AsRawDescriptor for PlatformEvent {
as_raw_descriptor(&self) -> RawDescriptor227     fn as_raw_descriptor(&self) -> RawDescriptor {
228         self.event_handle.as_raw_descriptor()
229     }
230 }
231 
232 impl FromRawDescriptor for PlatformEvent {
233     // SAFETY: Safe because the descriptor is expected to be valid.
from_raw_descriptor(descriptor: RawDescriptor) -> Self234     unsafe fn from_raw_descriptor(descriptor: RawDescriptor) -> Self {
235         PlatformEvent {
236             event_handle: SafeDescriptor::from_raw_descriptor(descriptor),
237         }
238     }
239 }
240 
241 impl AsRawHandle for PlatformEvent {
as_raw_handle(&self) -> RawHandle242     fn as_raw_handle(&self) -> RawHandle {
243         self.as_raw_descriptor()
244     }
245 }
246 
247 impl IntoRawDescriptor for PlatformEvent {
into_raw_descriptor(self) -> RawDescriptor248     fn into_raw_descriptor(self) -> RawDescriptor {
249         self.event_handle.into_raw_descriptor()
250     }
251 }
252 
253 impl From<PlatformEvent> for SafeDescriptor {
from(evt: PlatformEvent) -> Self254     fn from(evt: PlatformEvent) -> Self {
255         evt.event_handle
256     }
257 }
258 
259 impl From<SafeDescriptor> for PlatformEvent {
from(sd: SafeDescriptor) -> Self260     fn from(sd: SafeDescriptor) -> Self {
261         PlatformEvent { event_handle: sd }
262     }
263 }
264 
265 // Safety:
266 // PlatformEvent is safe for send & Sync despite containing a raw handle to its
267 // file mapping object. As long as the instance to PlatformEvent stays alive, this
268 // pointer will be a valid handle.
269 unsafe impl Send for PlatformEvent {}
270 // Safety: See comments for impl Send
271 unsafe impl Sync for PlatformEvent {}
272 
273 #[cfg(test)]
274 mod tests {
275     use winapi::shared::winerror::WAIT_TIMEOUT;
276     use winapi::um::winbase::INFINITE;
277     use winapi::um::winbase::WAIT_OBJECT_0;
278 
279     use super::*;
280 
281     #[test]
new()282     fn new() {
283         PlatformEvent::new().unwrap();
284     }
285 
286     #[test]
read_write()287     fn read_write() {
288         let evt = PlatformEvent::new().unwrap();
289         evt.signal().unwrap();
290         assert_eq!(evt.wait(), Ok(()));
291     }
292 
293     #[test]
read_write_auto_reset()294     fn read_write_auto_reset() {
295         let evt = PlatformEvent::new_with_manual_reset(false).unwrap();
296         evt.signal().unwrap();
297 
298         // Wait for the notification.
299         // SAFETY: Safe because return value is checked.
300         let result = unsafe { WaitForSingleObject(evt.as_raw_descriptor(), INFINITE) };
301         assert_eq!(result, WAIT_OBJECT_0);
302 
303         // The notification should have reset since we already received it.
304         // SAFETY: Safe because return value is checked.
305         let result = unsafe { WaitForSingleObject(evt.as_raw_descriptor(), 0) };
306         assert_eq!(result, WAIT_TIMEOUT);
307     }
308 
309     #[test]
read_write_notifies_until_read()310     fn read_write_notifies_until_read() {
311         let evt = PlatformEvent::new().unwrap();
312         evt.signal().unwrap();
313 
314         // Wait for the notification.
315         // SAFETY: Safe because return value is checked.
316         let result = unsafe { WaitForSingleObject(evt.as_raw_descriptor(), INFINITE) };
317         assert_eq!(result, WAIT_OBJECT_0);
318 
319         // The notification should still be active because read wasn't called.
320         // SAFETY: Safe because return value is checked.
321         let result = unsafe { WaitForSingleObject(evt.as_raw_descriptor(), 0) };
322         assert_eq!(result, WAIT_OBJECT_0);
323 
324         // Read and ensure the notification has cleared.
325         evt.wait().expect("Failed to read event.");
326         // SAFETY: Safe because return value is checked.
327         let result = unsafe { WaitForSingleObject(evt.as_raw_descriptor(), 0) };
328         assert_eq!(result, WAIT_TIMEOUT);
329     }
330 
331     #[test]
clone()332     fn clone() {
333         let evt = PlatformEvent::new().unwrap();
334         let evt_clone = evt.try_clone().unwrap();
335         evt.signal().unwrap();
336         assert_eq!(evt_clone.wait(), Ok(()));
337     }
338 
339     #[test]
timeout()340     fn timeout() {
341         let evt = PlatformEvent::new().expect("failed to create event");
342         assert_eq!(
343             evt.wait_timeout(Duration::from_millis(1))
344                 .expect("failed to read from event with timeout"),
345             EventWaitResult::TimedOut
346         );
347     }
348 }
349