From 28d0f6785825a72abdabd9690094002604baf51d Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Wed, 19 Oct 2022 14:56:13 -0700 Subject: [PATCH] base: event: add Event::reset() API This allows resetting an Event without waiting on it. Windows already had this functionality in its EventExt, and we can provide an equivalent implementation for eventfd on Linux, so promote this function to the cross-platform Event type. BUG=b:231344063 TEST=tools/presubmit --all Change-Id: I6dba3cb2e0b2d702e8a3f0dacf5c25c1dd044a13 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3966480 Reviewed-by: Frederick Mayle Commit-Queue: Daniel Verkamp Reviewed-by: Noah Gold --- base/src/event.rs | 7 +++++++ base/src/sys/unix/event.rs | 10 ++++++++++ base/src/sys/windows/event.rs | 5 ----- cros_async/src/sys/windows/event.rs | 1 - 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/base/src/event.rs b/base/src/event.rs index ce6394fd5b..f82cf48493 100644 --- a/base/src/event.rs +++ b/base/src/event.rs @@ -69,6 +69,13 @@ impl Event { self.0.wait_timeout(timeout) } + /// Clears the event without blocking. + /// + /// If the event is not signaled, this has no effect and returns immediately. + pub fn reset(&self) -> Result<()> { + self.0.reset() + } + /// Clones the event. The event's state is shared between cloned instances. /// /// The documented caveats for `Event` also apply to a set of cloned instances, e.g., it is diff --git a/base/src/sys/unix/event.rs b/base/src/sys/unix/event.rs index 7083f94272..2b63e9e089 100644 --- a/base/src/sys/unix/event.rs +++ b/base/src/sys/unix/event.rs @@ -145,6 +145,16 @@ impl PlatformEvent { Ok(EventWaitResult::Signaled) } + /// See `Event::reset`. + pub fn reset(&self) -> Result<()> { + // If the eventfd is currently signaled (counter > 0), `wait_timeout()` will `read()` it to + // reset the count. Otherwise (if the eventfd is not signaled), `wait_timeout()` will return + // immediately since we pass a zero duration. We don't care about the EventWaitResult; we + // just want a non-blocking read to reset the counter. + let _: EventWaitResult = self.wait_timeout(Duration::ZERO)?; + Ok(()) + } + /// Clones this eventfd, internally creating a new file descriptor. The new eventfd will share /// the same underlying count within the kernel. pub fn try_clone(&self) -> Result { diff --git a/base/src/sys/windows/event.rs b/base/src/sys/windows/event.rs index 5390498c03..67fb2fe2b3 100644 --- a/base/src/sys/windows/event.rs +++ b/base/src/sys/windows/event.rs @@ -50,7 +50,6 @@ pub(crate) struct PlatformEvent { } pub trait EventExt { - fn reset(&self) -> Result<()>; fn new_with_manual_reset(manual_reset: bool) -> Result; fn new_auto_reset() -> Result; fn open(name: &str) -> Result; @@ -58,10 +57,6 @@ pub trait EventExt { } impl EventExt for Event { - fn reset(&self) -> Result<()> { - self.0.reset() - } - fn new_with_manual_reset(manual_reset: bool) -> Result { PlatformEvent::new_with_manual_reset(manual_reset).map(Event) } diff --git a/cros_async/src/sys/windows/event.rs b/cros_async/src/sys/windows/event.rs index 836561ebbd..b26ffe14d6 100644 --- a/cros_async/src/sys/windows/event.rs +++ b/cros_async/src/sys/windows/event.rs @@ -6,7 +6,6 @@ use std::mem::ManuallyDrop; use base::AsRawDescriptor; use base::Event; -use base::EventExt; use base::FromRawDescriptor; use crate::AsyncError;