Skip to main content

InterruptibleEvent

Struct InterruptibleEvent 

Source
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:

  1. The given deadline expires.
  2. At least one of the notify or interrupt functions were called after begin_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

Source

pub fn new() -> Arc<Self> ⓘ

Source

pub fn get_owner(&self) -> Option<Koid>

Returns the owner of the underlying futex or requeue target futex, if any.

Source

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.

Source

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.

Source

pub fn notify(&self)

Wake up the event normally.

If this function is called before begin_wait, this notification is ignored. Calling this function repeatedly has no effect. If both notify and interrupt are called, the state observed by block_until is a race.

Source

pub fn interrupt(&self)

Wake up the event because of an interruption.

If this function is called before begin_wait, this notification is ignored. Calling this function repeatedly has no effect. If both notify and interrupt are called, the state observed by block_until is a race.

Trait Implementations§

Source§

impl Debug for InterruptibleEvent

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for InterruptibleEvent

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T, D> Encode<Ambiguous1, D> for T
where D: ResourceDialect,

§

unsafe fn encode( self, _encoder: &mut Encoder<'_, D>, _offset: usize, _depth: Depth, ) -> Result<(), Error>

Encodes the object into the encoder’s buffers. Any handles stored in the object are swapped for Handle::INVALID. Read more
§

impl<T, D> Encode<Ambiguous2, D> for T
where D: ResourceDialect,

§

unsafe fn encode( self, _encoder: &mut Encoder<'_, D>, _offset: usize, _depth: Depth, ) -> Result<(), Error>

Encodes the object into the encoder’s buffers. Any handles stored in the object are swapped for Handle::INVALID. Read more
§

impl<F, N> FidlIntoNative<Box<N>> for F
where F: FidlIntoNative<N>,

§

fn fidl_into_native(self) -> Box<N>

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.