Struct async_task::Runnable

source ·
pub struct Runnable<M = ()> { /* private fields */ }
Expand description

A handle to a runnable task.

Every spawned task has a single Runnable handle, which only exists when the task is scheduled for running.

Method run() polls the task’s future once. Then, the Runnable vanishes and only reappears when its Waker wakes the task, thus scheduling it to be run again.

Dropping a Runnable cancels the task, which means its future won’t be polled again, and awaiting the Task after that will result in a panic.

§Examples

use async_task::Runnable;
use once_cell::sync::Lazy;
use std::{panic, thread};

// A simple executor.
static QUEUE: Lazy<flume::Sender<Runnable>> = Lazy::new(|| {
    let (sender, receiver) = flume::unbounded::<Runnable>();
    thread::spawn(|| {
        for runnable in receiver {
            let _ignore_panic = panic::catch_unwind(|| runnable.run());
        }
    });
    sender
});

// Create a task with a simple future.
let schedule = |runnable| QUEUE.send(runnable).unwrap();
let (runnable, task) = async_task::spawn(async { 1 + 2 }, schedule);

// Schedule the task and await its output.
runnable.schedule();
assert_eq!(smol::future::block_on(task), 3);

Implementations§

source§

impl<M> Runnable<M>

source

pub fn metadata(&self) -> &M

Get the metadata associated with this task.

Tasks can be created with a metadata object associated with them; by default, this is a () value. See the Builder::metadata() method for more information.

source

pub fn schedule(self)

Schedules the task.

This is a convenience method that passes the Runnable to the schedule function.

§Examples
// A function that schedules the task when it gets woken up.
let (s, r) = flume::unbounded();
let schedule = move |runnable| s.send(runnable).unwrap();

// Create a task with a simple future and the schedule function.
let (runnable, task) = async_task::spawn(async {}, schedule);

// Schedule the task.
assert_eq!(r.len(), 0);
runnable.schedule();
assert_eq!(r.len(), 1);
source

pub fn run(self) -> bool

Runs the task by polling its future.

Returns true if the task was woken while running, in which case the Runnable gets rescheduled at the end of this method invocation. Otherwise, returns false and the Runnable vanishes until the task is woken. The return value is just a hint: true usually indicates that the task has yielded, i.e. it woke itself and then gave the control back to the executor.

If the Task handle was dropped or if cancel() was called, then this method simply destroys the task.

If the polled future panics, this method propagates the panic, and awaiting the Task after that will also result in a panic.

§Examples
// A function that schedules the task when it gets woken up.
let (s, r) = flume::unbounded();
let schedule = move |runnable| s.send(runnable).unwrap();

// Create a task with a simple future and the schedule function.
let (runnable, task) = async_task::spawn(async { 1 + 2 }, schedule);

// Run the task and check its output.
runnable.run();
assert_eq!(smol::future::block_on(task), 3);
source

pub fn waker(&self) -> Waker

Returns a waker associated with this task.

§Examples
use smol::future;

// A function that schedules the task when it gets woken up.
let (s, r) = flume::unbounded();
let schedule = move |runnable| s.send(runnable).unwrap();

// Create a task with a simple future and the schedule function.
let (runnable, task) = async_task::spawn(future::pending::<()>(), schedule);

// Take a waker and run the task.
let waker = runnable.waker();
runnable.run();

// Reschedule the task by waking it.
assert_eq!(r.len(), 0);
waker.wake();
assert_eq!(r.len(), 1);
source

pub fn into_raw(self) -> NonNull<()>

Converts this task into a raw pointer.

To avoid a memory leak the pointer must be converted back to a Runnable using Runnable<M>::from_raw.

into_raw does not change the state of the Task, but there is no guarantee that it will be in the same state after calling Runnable<M>::from_raw, as the corresponding Task might have been dropped or cancelled.

§Examples
use async_task::{Runnable, spawn};
let (runnable, task) = spawn(async {}, |_| {});
let runnable_pointer = runnable.into_raw();

unsafe {
    // Convert back to an `Runnable` to prevent leak.
    let runnable = Runnable::<()>::from_raw(runnable_pointer);
    runnable.run();
    // Further calls to `Runnable::from_raw(runnable_pointer)` would be memory-unsafe.
}
// The memory was freed when `x` went out of scope above, so `runnable_pointer` is now dangling!
source

pub unsafe fn from_raw(ptr: NonNull<()>) -> Self

Converts a raw pointer into a Runnable.

§Safety

This method should only be used with raw pointers returned from Runnable<M>::into_raw. It is not safe to use the provided pointer once it is passed to from_raw. Crucially, it is unsafe to call from_raw multiple times with the same pointer - even if the resulting Runnable is not used - as internally async-task uses reference counting.

It is however safe to call Runnable<M>::into_raw on a Runnable created with from_raw or after the Task associated with a given Runnable has been dropped or cancelled.

The state of the Runnable created with from_raw is not specified.

§Examples
use async_task::{Runnable, spawn};
let (runnable, task) = spawn(async {}, |_| {});
let runnable_pointer = runnable.into_raw();

drop(task);
unsafe {
    // Convert back to an `Runnable` to prevent leak.
    let runnable = Runnable::<()>::from_raw(runnable_pointer);
    let did_poll = runnable.run();
    assert!(!did_poll);
    // Further calls to `Runnable::from_raw(runnable_pointer)` would be memory-unsafe.
}
// The memory was freed when `x` went out of scope above, so `runnable_pointer` is now dangling!

Trait Implementations§

source§

impl<M: Debug> Debug for Runnable<M>

source§

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

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

impl<M> Drop for Runnable<M>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<M> RefUnwindSafe for Runnable<M>

source§

impl<M: Send + Sync> Send for Runnable<M>

source§

impl<M: Send + Sync> Sync for Runnable<M>

source§

impl<M> UnwindSafe for Runnable<M>

Auto Trait Implementations§

§

impl<M> Freeze for Runnable<M>

§

impl<M> Unpin for Runnable<M>
where M: Unpin,

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.

source§

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

§

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

§

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.