fuchsia_async::scope

Struct Scope

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

A scope for managing async tasks. This scope is cancelled when dropped.

Scopes are how fuchsia-async implements structured concurrency. Every task is spawned on a scope, and runs until either the task completes or the scope is cancelled. In addition to owning tasks, scopes may own child scopes, forming a nested structure.

Scopes are usually joined or cancelled when the owning code is done with them. This makes it easier to reason about when a background task might still be running. Note that in multithreaded contexts it is safer to cancel and await a scope explicitly than to drop it, because the destructor is not synchronized with other threads that might be running a task.

Task::spawn and related APIs spawn on the root scope of the executor. New code is encouraged to spawn directly on scopes instead, passing their handles as a way of documenting when a function might spawn tasks that run in the background and reasoning about their side effects.

§Scope lifecycle

When a scope is created it is open, meaning it accepts new tasks. Scopes are closed when one of the following happens:

  1. When close() is called.
  2. When the scope is cancelled or dropped, the scope is closed immediately.
  3. When the scope is joined and all tasks complete, the scope is closed before the join future resolves.

When a scope is closed it no longer accepts tasks. Tasks spawned on the scope are dropped immediately, and their Task or JoinHandle futures never resolve. This applies transitively to all child scopes. Closed scopes cannot currently be reopened.

Scopes can also be detached, in which case they are never closed, and run until the completion of all tasks.

Implementations§

Source§

impl Scope

Source

pub fn new() -> Scope

Create a new scope.

The returned scope is a child of the current scope.

§Panics

May panic if not called in the context of an executor (e.g. within a call to run).

Source

pub fn current() -> ScopeHandle

Get the scope of the current task, or the global scope if there is no task being polled.

§Panics

May panic if not called in the context of an executor (e.g. within a call to run).

Source

pub fn global() -> ScopeHandle

Get the global scope of the executor.

This can be used to spawn tasks that live as long as the executor. Usually, this means until the end of the program or test. This should only be done for tasks where this is expected. If in doubt, spawn on a shorter lived scope instead.

In code that uses scopes, you are strongly encouraged to use this API instead of the spawn APIs on Task.

All scopes are descendants of the global scope.

§Panics

May panic if not called in the context of an executor (e.g. within a call to run).

Source

pub fn new_child(&self) -> Scope

Create a child scope.

Source

pub fn to_handle(&self) -> ScopeHandle

Create a ScopeHandle that may be used to spawn tasks on this scope.

This is a shorthand for scope.as_handle().clone().

Scope holds a ScopeHandle and implements Deref to make its methods available. Note that you should not call scope.clone(), even though the compiler allows it due to the Deref impl. Call this method instead.

Source

pub fn as_handle(&self) -> &ScopeHandle

Get a reference to a ScopeHandle that may be used to spawn tasks on this scope.

Scope holds a ScopeHandle and implements Deref to make its methods available. If you have a Scope but need a &ScopeHandle, prefer calling this method over the less readable &*scope.

Source

pub fn join(self) -> Join

Wait for all tasks in the scope and its children to complete.

New tasks will be accepted on the scope until every task completes and this future resolves.

Note that you can await a scope directly because it implements IntoFuture. scope.join().await is a more explicit form of scope.await.

Source

pub fn close(self) -> Join

Stop accepting new tasks on the scope. Returns a future that waits for every task on the scope to complete.

Source

pub fn cancel(self) -> impl Future<Output = ()>

Cancel all tasks in the scope and its children recursively.

Once the returned future resolves, no task on the scope will be polled again.

When a scope is cancelled it immediately stops accepting tasks. Handles of tasks spawned on the scope will pend forever.

Dropping the Scope object is equivalent to calling this method and discarding the returned future. Awaiting the future is preferred because it eliminates the possibility of a task poll completing on another thread after the scope object has been dropped, which can sometimes result in surprising behavior.

Source

pub fn detach(self)

Detach the scope, allowing its tasks to continue running in the background.

Tasks of a detached scope are still subject to join and cancel operations on parent scopes.

Methods from Deref<Target = ScopeHandle>§

Source

pub fn new_child(&self) -> Scope

Create a child scope.

Source

pub fn spawn( &self, future: impl Future<Output = ()> + Send + 'static, ) -> JoinHandle<()>

Spawn a new task on the scope.

Source

pub fn spawn_local( &self, future: impl Future<Output = ()> + 'static, ) -> JoinHandle<()>

Spawn a new task on the scope of a thread local executor.

NOTE: This is not supported with a SendExecutor and will cause a runtime panic. Use ScopeHandle::spawn instead.

Source

pub fn compute<T: Send + 'static>( &self, future: impl Future<Output = T> + Send + 'static, ) -> Task<T>

Like spawn, but for tasks that return a result.

NOTE: Unlike spawn, when tasks are dropped, the future will be cancelled.

Source

pub fn compute_local<T: 'static>( &self, future: impl Future<Output = T> + 'static, ) -> Task<T>

Like spawn, but for tasks that return a result.

NOTE: Unlike spawn, when tasks are dropped, the future will be cancelled.

NOTE: This is not supported with a SendExecutor and will cause a runtime panic. Use ScopeHandle::spawn instead.

Source

pub fn close(&self)

Stop the scope from accepting new tasks.

Note that unlike Scope::close, this does not return a future that waits for all tasks to complete. This could lead to resource leaks because it is not uncommon to access a TaskGroup from a task running on the scope itself. If such a task were to await a future returned by this method it would suspend forever waiting for itself to complete.

Source

pub async fn on_no_tasks(&self)

Wait for there to be no tasks. This is racy: as soon as this returns it is possible for another task to have been spawned on this scope.

Source

pub fn wake_all(&self)

Wake all the scope’s tasks so their futures will be polled again.

Trait Implementations§

Source§

impl Borrow<ScopeHandle> for Scope

Source§

fn borrow(&self) -> &ScopeHandle

Immutably borrows from an owned value. Read more
Source§

impl Deref for Scope

Source§

type Target = ScopeHandle

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl Drop for Scope

Cancel the scope and all of its tasks. Prefer using the Scope::cancel or Scope::join methods.

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl IntoFuture for Scope

Source§

type Output = ()

The output that the future will produce on completion.
Source§

type IntoFuture = Join

Which kind of future are we turning this into?
Source§

fn into_future(self) -> Self::IntoFuture

Creates a future from a value. Read more

Auto Trait Implementations§

§

impl Freeze for Scope

§

impl !RefUnwindSafe for Scope

§

impl Send for Scope

§

impl Sync for Scope

§

impl Unpin for Scope

§

impl !UnwindSafe for Scope

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> 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.

§

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<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.