Skip to main content

Dispatcher

Struct Dispatcher 

Source
pub struct Dispatcher { /* private fields */ }
Expand description

Provides services for managing work items on a thread.

§Threading

The object model is single-threaded and Rc-based; the dispatcher is the one entry point that can be used from other threads. A dispatcher is therefore handed out as Arc<Dispatcher> and is Send + Sync, and its API is split in two:

  • post, invoke, invoke_async and their variants can be called from any thread. Their callbacks (and results) must be Send.
  • post_local, invoke_local, invoke_async_local and their variants accept callbacks that are not Send (they may capture Rcs, Refs, …). They can only be called on the dispatcher thread, which is checked at run time: calling them from another thread panics. The callback is kept in thread-local storage and never leaves the thread.

Timers (DispatcherTimer), the shutdown and unhandled-exception events and everything else that takes non-Send handlers is likewise bound to the dispatcher thread. So is the platform implementation (IDispatcherImpl): other threads only ever use its IDispatcherSignal.

§Async

The dispatcher is also an executor for futures, which takes the place of the synchronization context of the reference implementation: invoke_async_task and DispatcherTaskScheduler run a future on the dispatcher thread, polling it from jobs queued at a fixed priority; resume, yield_now and await_with_priority change the priority at which an async block continues. No async runtime is involved.

§Panics in callbacks

What the reference implementation does with exceptions is done here with panics: a panic in a posted callback goes through unhandled_exception_filter and unhandled_exception and is re-raised on the dispatcher thread unless a handler marks it as handled; a panic in an invoke/invoke_async callback is captured and re-raised to whoever waits for the operation. On targets that abort on panic none of this applies.

Implementations§

Source§

impl Dispatcher

Source

pub fn supports_run_loops(&self) -> bool

Whether the platform implementation can run nested event loops. When this is false, push_frame and main_loop are not available.

Source

pub fn check_access(&self) -> bool

Checks that the current thread is the dispatcher thread.

Source

pub fn verify_access(&self)

Checks that the current thread is the dispatcher thread and panics if not.

Source

pub fn thread(&self) -> ThreadId

The thread this dispatcher belongs to.

Source

pub fn platform_impl(&self) -> Rc<dyn IDispatcherImpl>

The platform implementation currently in use.

§Panics

Panics when called from a thread other than the dispatcher thread: the implementation belongs to that thread.

Source§

impl Dispatcher

Source

pub fn unhandled_exception( &self, handler: impl for<'a> Fn(&DispatcherUnhandledExceptionEventArgs<'a>) + 'static, ) -> Rc<dyn IDisposable>

Occurs when a callback posted with post or post_local panics and the panic is not caught.

A handler can mark the panic as handled, which stops it from being re-raised on the dispatcher thread. Handlers must be written with care to avoid secondary panics.

Callbacks run through invoke/invoke_async do not raise this event: their panic is delivered to whoever waits for the operation.

§Panics

Panics when called from a thread other than the dispatcher thread.

Source

pub fn unhandled_exception_filter( &self, handler: impl for<'a> Fn(&DispatcherUnhandledExceptionFilterEventArgs<'a>) + 'static, ) -> Rc<dyn IDisposable>

Occurs first when a posted callback panics, to decide whether unhandled_exception is raised at all.

The filter runs regardless of whether there are unhandled_exception handlers. Setting request_catch to false skips the unhandled_exception event.

§Panics

Panics when called from a thread other than the dispatcher thread.

Source§

impl Dispatcher

Synchronous execution. The callbacks of invoke and its variants can come from any thread and must be Send; the invoke_local variants accept any callback but can only be called on the dispatcher thread.

Source

pub fn invoke<R: Send + 'static>( &self, callback: impl FnOnce() -> R + Send + 'static, ) -> Result<R, OperationCanceledError>

Executes the specified callback synchronously on the thread that the dispatcher was created on, at DispatcherPriority::SEND.

Returns Err when the operation was aborted before it ran (for instance because the dispatcher has shut down).

§Panics

Re-raises the panic of the callback.

Source

pub fn invoke_with_priority<R: Send + 'static>( &self, callback: impl FnOnce() -> R + Send + 'static, priority: DispatcherPriority, ) -> Result<R, OperationCanceledError>

Executes the specified callback synchronously with the specified priority on the thread that the dispatcher was created on.

Source

pub fn invoke_with_cancellation<R: Send + 'static>( &self, callback: impl FnOnce() -> R + Send + 'static, priority: DispatcherPriority, cancellation_token: &CancellationToken, ) -> Result<R, OperationCanceledError>

Executes the specified callback synchronously with the specified priority on the thread that the dispatcher was created on.

cancellation_token cancels the operation as long as it has not started. Returns Err when the token is already canceled.

Source

pub fn invoke_with_timeout<R: Send + 'static>( &self, callback: impl FnOnce() -> R + Send + 'static, priority: DispatcherPriority, cancellation_token: &CancellationToken, timeout: Duration, ) -> Result<R, DispatcherInvokeError>

Executes the specified callback synchronously with the specified priority on the thread that the dispatcher was created on, giving up when the operation has not started within timeout.

The timeout only applies to the time the operation spends in the queue: once it has started, the call waits for it to complete. When the operation is still pending after timeout it is aborted and DispatcherInvokeError::Timeout is returned.

On the dispatcher thread the queue is pumped while waiting and the timeout is measured with the dispatcher clock.

Source

pub fn invoke_local<R: 'static>( &self, callback: impl FnOnce() -> R + 'static, ) -> Result<R, OperationCanceledError>

Like invoke for callbacks that are not Send.

§Panics

Panics when called from a thread other than the dispatcher thread.

Source

pub fn invoke_local_with_priority<R: 'static>( &self, callback: impl FnOnce() -> R + 'static, priority: DispatcherPriority, ) -> Result<R, OperationCanceledError>

Like invoke_with_priority for callbacks that are not Send.

§Panics

Panics when called from a thread other than the dispatcher thread.

Source

pub fn invoke_local_with_cancellation<R: 'static>( &self, callback: impl FnOnce() -> R + 'static, priority: DispatcherPriority, cancellation_token: &CancellationToken, ) -> Result<R, OperationCanceledError>

Like invoke_with_cancellation for callbacks that are not Send.

§Panics

Panics when called from a thread other than the dispatcher thread.

Source

pub fn invoke_local_with_timeout<R: 'static>( &self, callback: impl FnOnce() -> R + 'static, priority: DispatcherPriority, cancellation_token: &CancellationToken, timeout: Duration, ) -> Result<R, DispatcherInvokeError>

Like invoke_with_timeout for callbacks that are not Send.

§Panics

Panics when called from a thread other than the dispatcher thread.

Source§

impl Dispatcher

Asynchronous execution; see Dispatcher for the Send/local split.

Source

pub fn invoke_async<R: Send + 'static>( &self, callback: impl FnOnce() -> R + Send + 'static, ) -> DispatcherOperation<R> ⓘ

Executes the specified callback asynchronously on the thread that the dispatcher was created on, at DispatcherPriority::DEFAULT.

The returned operation can be awaited, waited for, aborted and re-prioritized.

Source

pub fn invoke_async_with_priority<R: Send + 'static>( &self, callback: impl FnOnce() -> R + Send + 'static, priority: DispatcherPriority, ) -> DispatcherOperation<R> ⓘ

Executes the specified callback asynchronously with the specified priority on the thread that the dispatcher was created on.

Source

pub fn invoke_async_with_cancellation<R: Send + 'static>( &self, callback: impl FnOnce() -> R + Send + 'static, priority: DispatcherPriority, cancellation_token: &CancellationToken, ) -> DispatcherOperation<R> ⓘ

Executes the specified callback asynchronously with the specified priority on the thread that the dispatcher was created on.

cancellation_token aborts the operation as long as it has not started.

Source

pub fn invoke_async_local<R: 'static>( &self, callback: impl FnOnce() -> R + 'static, ) -> DispatcherOperation<R> ⓘ

Like invoke_async for callbacks that are not Send.

§Panics

Panics when called from a thread other than the dispatcher thread.

Source

pub fn invoke_async_local_with_priority<R: 'static>( &self, callback: impl FnOnce() -> R + 'static, priority: DispatcherPriority, ) -> DispatcherOperation<R> ⓘ

Like invoke_async_with_priority for callbacks that are not Send.

§Panics

Panics when called from a thread other than the dispatcher thread.

Source

pub fn invoke_async_local_with_cancellation<R: 'static>( &self, callback: impl FnOnce() -> R + 'static, priority: DispatcherPriority, cancellation_token: &CancellationToken, ) -> DispatcherOperation<R> ⓘ

Like invoke_async_with_cancellation for callbacks that are not Send.

§Panics

Panics when called from a thread other than the dispatcher thread.

Source

pub fn invoke_async_task<F, Fut>( &self, callback: F, ) -> DispatcherTask<Fut::Output> ⓘ
where F: FnOnce() -> Fut + Send + 'static, Fut: Future + 'static, Fut::Output: Send + 'static,

Executes the specified callback on the dispatcher thread and then runs the future it returns there, at DispatcherPriority::DEFAULT.

The returned task completes when the future has completed; see invoke_async_task_with_priority.

Source

pub fn invoke_async_task_with_priority<F, Fut>( &self, callback: F, priority: DispatcherPriority, ) -> DispatcherTask<Fut::Output> ⓘ
where F: FnOnce() -> Fut + Send + 'static, Fut: Future + 'static, Fut::Output: Send + 'static,

Executes the specified callback with the specified priority on the dispatcher thread and then runs the future it returns there.

The callback can come from any thread; the future it creates never leaves the dispatcher thread and does not have to be Send. The future is polled for the first time right after the callback, inside the same job, and afterwards from jobs of the same priority.

The returned task completes when the future has completed. It is canceled when the operation is aborted before the callback ran or the dispatcher shuts down before the future is done, and it fails with the panic of the callback or the future.

Source

pub fn invoke_async_task_local<F, Fut>( &self, callback: F, ) -> DispatcherTask<Fut::Output> ⓘ
where F: FnOnce() -> Fut + 'static, Fut: Future + 'static, Fut::Output: 'static,

Like invoke_async_task for callbacks and results that are not Send.

§Panics

Panics when called from a thread other than the dispatcher thread.

Source

pub fn invoke_async_task_local_with_priority<F, Fut>( &self, callback: F, priority: DispatcherPriority, ) -> DispatcherTask<Fut::Output> ⓘ
where F: FnOnce() -> Fut + 'static, Fut: Future + 'static, Fut::Output: 'static,

Like invoke_async_task_with_priority for callbacks and results that are not Send.

§Panics

Panics when called from a thread other than the dispatcher thread.

Source

pub fn post( &self, action: impl FnOnce() + Send + 'static, priority: DispatcherPriority, )

Posts an action that will be invoked on the dispatcher thread.

Can be called from any thread. A panic raised by the action goes through the unhandled-exception events of the dispatcher.

Source

pub fn post_local( &self, action: impl FnOnce() + 'static, priority: DispatcherPriority, )

Posts an action that is not Send to be invoked on the dispatcher thread.

§Panics

Panics when called from a thread other than the dispatcher thread.

Source

pub fn await_with_priority<F: Future>( &self, task: F, priority: DispatcherPriority, ) -> DispatcherPriorityTaskAwaitable<F> ⓘ

Returns a future that awaits task and then resumes the awaiting code from a job of this dispatcher with the given priority, yielding the output of task.

Source

pub fn resume(&self) -> DispatcherPriorityAwaitable ⓘ

Returns a future that resumes on this dispatcher’s thread at DispatcherPriority::BACKGROUND when awaited.

Source

pub fn resume_with_priority( &self, priority: DispatcherPriority, ) -> DispatcherPriorityAwaitable ⓘ

Returns a future that resumes on this dispatcher’s thread at the given priority when awaited.

Source

pub fn yield_now() -> DispatcherPriorityAwaitable ⓘ

Returns a future that yields to the current dispatcher, letting it process other work, and resumes at DispatcherPriority::BACKGROUND.

Source

pub fn yield_with_priority( priority: DispatcherPriority, ) -> DispatcherPriorityAwaitable ⓘ

Returns a future that yields to the current dispatcher and resumes at the given priority.

Source§

impl Dispatcher

Source

pub fn shutdown_started( &self, handler: impl Fn(&Arc<Dispatcher>) + 'static, ) -> Rc<dyn IDisposable>

Raised when the dispatcher is shutting down.

§Panics

Panics when called from a thread other than the dispatcher thread.

Source

pub fn shutdown_finished( &self, handler: impl Fn(&Arc<Dispatcher>) + 'static, ) -> Rc<dyn IDisposable>

Raised when the dispatcher is shut down.

§Panics

Panics when called from a thread other than the dispatcher thread.

Source

pub fn push_frame(&self, frame: &Arc<DispatcherFrame>)

Push an execution frame.

§Panics

Panics when the platform implementation does not support run loops (see supports_run_loops), when the dispatcher has shut down, when processing is disabled and when called from another thread.

Source

pub fn main_loop(&self, cancellation_token: &CancellationToken)

Runs the dispatcher’s main loop until cancellation_token is canceled.

§Panics

See push_frame.

Source

pub fn exit_all_frames(&self)

Requests that all nested frames exit.

Source

pub fn begin_invoke_shutdown(&self, priority: DispatcherPriority)

Begins the process of shutting down the dispatcher.

Source

pub fn invoke_shutdown(&self)

Initiates the shutdown process of the dispatcher synchronously.

Source

pub fn disable_processing(&self) -> DispatcherProcessingDisabled

Disable the event processing of the dispatcher.

This is an advanced method intended to eliminate the chance of unrelated reentrancy. While processing is disabled no one is allowed to push a frame and no job processing is permitted. Processing is enabled again by disposing the returned value.

Source§

impl Dispatcher

Source

pub fn run_jobs(&self, priority: Option<DispatcherPriority>)

Force-runs all dispatcher operations ignoring any pending OS events, use with caution.

None runs every active job.

Source

pub fn has_jobs_with_priority(&self, priority: DispatcherPriority) -> bool

Whether a job with at least the given priority is queued.

Source§

impl Dispatcher

Source

pub fn current_dispatcher() -> Arc<Dispatcher> ⓘ

The dispatcher of the calling thread. It is created when the thread does not have one yet and then lives until the thread exits.

Source

pub fn from_thread(thread: ThreadId) -> Option<Arc<Dispatcher>>

The dispatcher of thread, if that thread has one.

Source

pub fn ui_thread() -> Arc<Dispatcher> ⓘ

Gets the dispatcher for the UI thread: the first dispatcher that was created in the process.

Control and library authors are encouraged to use current_dispatcher and the dispatcher of the object at hand instead.

Source

pub fn initialize_ui_thread_dispatcher_legacy( impl_: Rc<dyn IPlatformThreadingInterface>, )

Installs the platform implementation of the UI thread dispatcher, adapting a legacy threading interface.

Source

pub fn initialize_ui_thread_dispatcher(impl_: Rc<dyn IDispatcherImpl>)

Installs the platform implementation of the UI thread dispatcher.

§Panics

Panics when not called on the UI thread or when the UI thread dispatcher has already been initialized.

Source§

impl Dispatcher

Source

pub fn now(&self) -> i64

The current time of the platform implementation, in milliseconds.

Dispatcher thread only; a dispatcher that has been reset reports 0.

Source§

impl Dispatcher

This impl block contains no public items.

Test support for the other crates of the workspace: the reference gives its test assemblies access to the internal timer queue.

Source§

impl Dispatcher

Source

pub fn to_task_scheduler(&self) -> DispatcherTaskScheduler

Gets a scheduler which runs futures on this dispatcher. The priority is taken from the current FerroSynchronizationContext if one is available. Otherwise, DispatcherPriority::DEFAULT is used.

Source

pub fn to_task_scheduler_with_priority( &self, priority: DispatcherPriority, ) -> DispatcherTaskScheduler

Gets a scheduler which runs futures on this dispatcher with the specified priority.

Trait Implementations§

Source§

impl Debug for Dispatcher

Source§

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

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

impl IDispatcher for Dispatcher

Source§

fn check_access(&self) -> bool

Determines whether the calling thread is the thread associated with this dispatcher.
Source§

fn verify_access(&self)

Panics when the calling thread is not the thread associated with this dispatcher.
Source§

fn post(&self, action: Box<dyn FnOnce() + Send>, priority: DispatcherPriority)

Posts an action that will be invoked on the dispatcher thread. 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
Source§

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

Source§

fn static_constructor()

The static constructor of a type: work done once per thread, after the properties of the type are registered and before its first instance exists (class handlers, affects_render, metadata overrides). Read more
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, 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.