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