Struct glommio::ScopedTask

source ·
pub struct ScopedTask<'a, T>(/* private fields */);
Expand description

A spawned future that cannot be detached, and has a predictable lifetime.

Because their lifetimes are bounded, you don’t need to make sure that data you pass to the ScopedTask is 'static, which can be cheaper (no need to reference count). If you, however, would like to .detach this task and have it run in the background, consider using Task instead.

Tasks are also futures themselves and yield the output of the spawned future.

When a task is dropped, its gets canceled and won’t be polled again. To cancel a task a bit more gracefully and wait until it stops running, use the cancel() method.

Tasks that panic get immediately canceled. Awaiting a canceled task also causes a panic.

§Safety

ScopedTask is safe to use so long as it is guaranteed to be either awaited or dropped. Rust does not guarantee that destructors will be called, and if they are not, ScopedTasks can be kept alive after the scope is terminated.

Typically, the only situations in which drop is not executed are:

If you believe any of the above situations are present (the first one is, of course, considerably easier to spot), avoid using the ScopedTask.

§Examples

use glommio::LocalExecutor;

let ex = LocalExecutor::default();

ex.run(async {
    let a = 2;
    let task = unsafe {
        glommio::spawn_scoped_local(async {
            println!("Hello from a task!");
            1 + a // this is a reference, and it works just fine
        })
    };

    assert_eq!(task.await, 3);
});

The usual borrow checker rules apply. A ScopedTask can acquire a mutable reference to a variable just fine:

let mut a = 2;
let task = unsafe {
    glommio::spawn_scoped_local(async {
        a = 3;
    })
};
task.await;
assert_eq!(a, 3);

But until the task completes, the reference is mutably held, so we can no longer immutably reference it:

let mut a = 2;
let task = unsafe {
    glommio::scoped_local(async {
        a = 3;
    })
};
assert_eq!(a, 3); // task hasn't completed yet!
task.await;

You can still use Cell and RefCell normally to work around this. Just keep in mind that there is no guarantee of ordering for execution of tasks, and if the task has not yet finished the value may or may not have changed (as with any interior mutability)

let a = Cell::new(2);
let task = unsafe {
    glommio::spawn_scoped_local(async {
        a.set(3);
    })
};

assert!(a.get() == 3 || a.get() == 2); // impossible to know if it will be 2 or 3
task.await;
assert_eq!(a.get(), 3); // The task finished now.
//

The following code, however, will access invalid memory as drop is never executed

{
    let a = &mut "mayhem";
    let task = unsafe {
        glommio::spawn_scoped_local(async {
            *a = "doom";
        })
    };
    std::mem::forget(task);
}

Implementations§

source§

impl<'a, T> ScopedTask<'a, T>

source

pub async fn cancel(self) -> Option<T>

Cancels the task and waits for it to stop running.

Returns the task’s output if it was completed just before it got canceled, or None if it didn’t complete.

While it’s possible to simply drop the ScopedTask to cancel it, this is a cleaner way of canceling because it also waits for the task to stop running.

§Examples
use futures_lite::future;
use glommio::LocalExecutor;

let ex = LocalExecutor::default();

ex.run(async {
    let task = unsafe {
        glommio::spawn_scoped_local(async {
            loop {
                println!("Even though I'm in an infinite loop, you can still cancel me!");
                future::yield_now().await;
            }
        })
    };

    task.cancel().await;
});

Trait Implementations§

source§

impl<'a, T: Debug> Debug for ScopedTask<'a, T>

source§

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

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

impl<'a, T> Future for ScopedTask<'a, T>

§

type Output = T

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempt to resolve the future to a final value, registering the current task for wakeup if the value is not yet available. Read more

Auto Trait Implementations§

§

impl<'a, T> Freeze for ScopedTask<'a, T>

§

impl<'a, T> RefUnwindSafe for ScopedTask<'a, T>
where T: RefUnwindSafe,

§

impl<'a, T> !Send for ScopedTask<'a, T>

§

impl<'a, T> !Sync for ScopedTask<'a, T>

§

impl<'a, T> Unpin for ScopedTask<'a, T>

§

impl<'a, T> UnwindSafe for ScopedTask<'a, T>

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<F> FutureExt for F
where F: Future + ?Sized,

source§

fn poll(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where Self: Unpin,

A convenience for calling Future::poll() on !Unpin types.
source§

fn or<F>(self, other: F) -> Or<Self, F>
where Self: Sized, F: Future<Output = Self::Output>,

Returns the result of self or other future, preferring self if both are ready. Read more
source§

fn race<F>(self, other: F) -> Race<Self, F>
where Self: Sized, F: Future<Output = Self::Output>,

Returns the result of self or other future, with no preference if both are ready. Read more
source§

fn catch_unwind(self) -> CatchUnwind<Self>
where Self: Sized + UnwindSafe,

Catches panics while polling the future. Read more
source§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where Self: Sized + Send + 'a,

Boxes the future and changes its type to dyn Future + Send + 'a. Read more
source§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where Self: Sized + 'a,

Boxes the future and changes its type to dyn Future + 'a. Read more
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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<F> IntoFuture for F
where F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

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

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Pointable for T

source§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
source§

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

Initializes a with the given initializer. Read more
source§

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

Dereferences the given pointer. Read more
source§

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

Mutably dereferences the given pointer. Read more
source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
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<F, T, E> TryFuture for F
where F: Future<Output = Result<T, E>> + ?Sized,

§

type Ok = T

The type of successful values yielded by this future
§

type Error = E

The type of failures yielded by this future
source§

fn try_poll( self: Pin<&mut F>, cx: &mut Context<'_> ) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
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.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more