xref: /aosp_15_r20/external/crosvm/cros_async/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::mem::ManuallyDrop;
6 
7 use base::AsRawDescriptor;
8 use base::Event;
9 use base::FromRawDescriptor;
10 
11 use crate::AsyncError;
12 use crate::AsyncResult;
13 use crate::EventAsync;
14 use crate::Executor;
15 
16 impl EventAsync {
new(event: Event, ex: &Executor) -> AsyncResult<EventAsync>17     pub fn new(event: Event, ex: &Executor) -> AsyncResult<EventAsync> {
18         ex.async_from(event).map(|io_source| EventAsync {
19             io_source,
20             reset_after_read: true,
21         })
22     }
23 
24     /// For Windows events, especially those used in overlapped IO, we don't want to reset them
25     /// after "reading" from them because the signaling state is entirely managed by the kernel.
new_without_reset(event: Event, ex: &Executor) -> AsyncResult<EventAsync>26     pub fn new_without_reset(event: Event, ex: &Executor) -> AsyncResult<EventAsync> {
27         ex.async_from(event).map(|io_source| EventAsync {
28             io_source,
29             reset_after_read: false,
30         })
31     }
32 
33     /// Given a non-owning raw descriptor to an Event, will make a clone to construct this async
34     /// Event. Use for cases where you have a valid raw event descriptor, but don't own it.
clone_raw_without_reset( descriptor: &dyn AsRawDescriptor, ex: &Executor, ) -> AsyncResult<EventAsync>35     pub fn clone_raw_without_reset(
36         descriptor: &dyn AsRawDescriptor,
37         ex: &Executor,
38     ) -> AsyncResult<EventAsync> {
39         Self::new_without_reset(
40             // SAFETY:
41             // Safe because:
42             // * the underlying Event should be validated by the caller.
43             // * we do NOT take ownership of the underlying Event. If we did that would cause an
44             //   early free (and later a double free @ the end of this scope). This is why we have
45             //   to wrap it in ManuallyDrop.
46             // * we own the clone that is produced exclusively, so it is safe to take ownership of
47             // it.
48             unsafe {
49                 ManuallyDrop::new(Event::from_raw_descriptor(descriptor.as_raw_descriptor()))
50             }
51             .try_clone()
52             .map_err(AsyncError::EventAsync)?,
53             ex,
54         )
55     }
56 
57     /// Gets the next value from the eventfd.
next_val(&self) -> AsyncResult<u64>58     pub async fn next_val(&self) -> AsyncResult<u64> {
59         self.io_source.wait_for_handle().await?;
60 
61         if self.reset_after_read {
62             self.io_source
63                 .as_source()
64                 .reset()
65                 .map_err(AsyncError::EventAsync)?;
66         }
67         Ok(0)
68     }
69 }
70