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