// Copyright 2022 The ChromiumOS Authors1// Use of this source code is governed by a BSD-style license that can be2// found in the LICENSE file.34use std::mem::ManuallyDrop;56use base::AsRawDescriptor;7use base::Event;8use base::FromRawDescriptor;910use crate::AsyncError;11use crate::AsyncResult;12use crate::EventAsync;13use crate::Executor;1415impl EventAsync {16pub fn new(event: Event, ex: &Executor) -> AsyncResult<EventAsync> {17ex.async_from(event).map(|io_source| EventAsync {18io_source,19reset_after_read: true,20})21}2223/// For Windows events, especially those used in overlapped IO, we don't want to reset them24/// after "reading" from them because the signaling state is entirely managed by the kernel.25pub fn new_without_reset(event: Event, ex: &Executor) -> AsyncResult<EventAsync> {26ex.async_from(event).map(|io_source| EventAsync {27io_source,28reset_after_read: false,29})30}3132/// Given a non-owning raw descriptor to an Event, will make a clone to construct this async33/// Event. Use for cases where you have a valid raw event descriptor, but don't own it.34pub fn clone_raw_without_reset(35descriptor: &dyn AsRawDescriptor,36ex: &Executor,37) -> AsyncResult<EventAsync> {38Self::new_without_reset(39// SAFETY:40// Safe because:41// * the underlying Event should be validated by the caller.42// * we do NOT take ownership of the underlying Event. If we did that would cause an43// early free (and later a double free @ the end of this scope). This is why we have44// to wrap it in ManuallyDrop.45// * we own the clone that is produced exclusively, so it is safe to take ownership of46// it.47unsafe {48ManuallyDrop::new(Event::from_raw_descriptor(descriptor.as_raw_descriptor()))49}50.try_clone()51.map_err(AsyncError::EventAsync)?,52ex,53)54}5556/// Gets the next value from the eventfd.57pub async fn next_val(&self) -> AsyncResult<u64> {58self.io_source.wait_for_handle().await?;5960if self.reset_after_read {61self.io_source62.as_source()63.reset()64.map_err(AsyncError::EventAsync)?;65}66Ok(0)67}68}697071