pub struct InterruptibleEvent { /* private fields */ }Expand description
A blocking object that can either be notified normally or interrupted
To block using an InterruptibleEvent, first call begin_wait. At this point, the event is
in the “waiting” state, and future calls to notify or interrupt will terminate the wait.
After begin_wait returns, call block_until to block the current thread until one of the
following conditions occur:
- The given deadline expires.
- At least one of the
notifyorinterruptfunctions were called afterbegin_wait.
It’s safe to call notify or interrupt at any time. However, calls to begin_wait and
block_until must alternate, starting with begin_wait.
InterruptibleEvent uses two-phase waiting so that clients can register for notification,
perform some related work, and then start blocking. This approach ensures that clients do not
miss notifications that arrive after they perform the related work but before they actually
start blocking.
§Priority Inheritance and Dynamic Futex Owner Assignment
InterruptibleEvent supports Zircon Priority Inheritance (PI). If the target owner thread is
known at wait time, it can be passed directly to block_until / zx_futex_wait.
When the owner thread is not known when waiting begins (for example, when a transaction is
queued to a process-wide worker pool), assign_new_owner can be called by the worker thread
that later dequeues the work item. assign_new_owner uses zx_futex_requeue to atomically
transfer waiting threads to a secondary requeue_target futex while designating the worker
thread as the futex PI owner.
TODO(https://fxbug.dev/542307988): The long-term solution is a dedicated Zircon syscall (such as
zx_futex_assign_owner) to assign or update the PI owner of an existing futex without
requiring a secondary requeue target futex.
Implementations§
Source§impl InterruptibleEvent
impl InterruptibleEvent
pub fn new() -> Arc<Self> ⓘ
Sourcepub fn get_owner(&self) -> Option<Koid>
pub fn get_owner(&self) -> Option<Koid>
Returns the owner of the underlying futex or requeue target futex, if any.
Sourcepub fn begin_wait<'a>(self: &'a Arc<Self>) -> EventWaitGuard<'a>
pub fn begin_wait<'a>(self: &'a Arc<Self>) -> EventWaitGuard<'a>
Called to initiate a wait.
Calls to notify or interrupt after this function returns will cause the event to wake
up. Calls to those functions prior to calling begin_wait will be ignored.
Once called, this function cannot be called again until block_until returns. Otherwise,
this function will panic.
Sourcepub fn assign_new_owner(&self, new_owner: &Thread) -> Result<(), Status>
pub fn assign_new_owner(&self, new_owner: &Thread) -> Result<(), Status>
Assigns new_owner as the Priority Inheritance (PI) owner for waiting thread(s).
If threads are currently waiting on futex, this dynamically requeues them to
requeue_target, designating new_owner as the futex PI owner.
This establishes Zircon Priority Inheritance (PI) from the waiting thread(s) to
new_owner when the owner was not known at begin_wait time.
Note: This can only be called once per begin_wait cycle (while the event is in the
WAITING state). If the event is not waiting or has already been requeued/notified,
this returns Err(zx::Status::BAD_STATE).
TODO(https://fxbug.dev/542307988): Replace this requeue pattern with a dedicated Zircon syscall to assign a new owner to a futex with waiting threads once available.
Trait Implementations§
Source§impl Debug for InterruptibleEvent
impl Debug for InterruptibleEvent
Auto Trait Implementations§
impl !Freeze for InterruptibleEvent
impl RefUnwindSafe for InterruptibleEvent
impl Send for InterruptibleEvent
impl Sync for InterruptibleEvent
impl Unpin for InterruptibleEvent
impl UnsafeUnpin for InterruptibleEvent
impl UnwindSafe for InterruptibleEvent
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T, D> Encode<Ambiguous1, D> for Twhere
D: ResourceDialect,
impl<T, D> Encode<Ambiguous1, D> for Twhere
D: ResourceDialect,
§impl<T, D> Encode<Ambiguous2, D> for Twhere
D: ResourceDialect,
impl<T, D> Encode<Ambiguous2, D> for Twhere
D: ResourceDialect,
§impl<F, N> FidlIntoNative<Box<N>> for Fwhere
F: FidlIntoNative<N>,
impl<F, N> FidlIntoNative<Box<N>> for Fwhere
F: FidlIntoNative<N>,
fn fidl_into_native(self) -> Box<N>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more