• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         // Safe because:
40         // a) the underlying Event should be validated by the caller.
41         // b) we do NOT take ownership of the underlying Event. If we did that would cause an early
42         //    free (and later a double free @ the end of this scope). This is why we have to wrap
43         //    it in ManuallyDrop.
44         // c) we own the clone that is produced exclusively, so it is safe to take ownership of it.
45         Self::new_without_reset(
46             unsafe {
47                 ManuallyDrop::new(Event::from_raw_descriptor(descriptor.as_raw_descriptor()))
48             }
49             .try_clone()
50             .map_err(AsyncError::EventAsync)?,
51             ex,
52         )
53     }
54 
55     /// Gets the next value from the eventfd.
next_val(&self) -> AsyncResult<u64>56     pub async fn next_val(&self) -> AsyncResult<u64> {
57         let res = self.io_source.wait_for_handle().await;
58 
59         if self.reset_after_read {
60             self.io_source
61                 .as_source()
62                 .reset()
63                 .map_err(AsyncError::EventAsync)?;
64         }
65         res
66     }
67 }
68