Skip to main content

vortex_io/runtime/
smol.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use futures::future::BoxFuture;
5
6use crate::runtime::AbortHandle;
7use crate::runtime::AbortHandleRef;
8use crate::runtime::Executor;
9
10// NOTE(ngates): we implement this for a Weak reference to adhere to the constraint that this
11//  trait should not hold strong references to the underlying runtime.
12impl Executor for smol::Executor<'static> {
13    fn spawn(&self, fut: BoxFuture<'static, ()>) -> AbortHandleRef {
14        SmolAbortHandle::new_handle(smol::Executor::spawn(self, fut))
15    }
16
17    fn spawn_cpu(&self, task: Box<dyn FnOnce() + Send + 'static>) -> AbortHandleRef {
18        // For now, we spawn CPU work back onto the same execution.
19        SmolAbortHandle::new_handle(smol::Executor::spawn(self, async move { task() }))
20    }
21
22    fn spawn_blocking_io(&self, task: Box<dyn FnOnce() + Send + 'static>) -> AbortHandleRef {
23        SmolAbortHandle::new_handle(smol::unblock(task))
24    }
25}
26
27/// An abort handle for a `smol::Task`.
28pub(crate) struct SmolAbortHandle<T> {
29    task: Option<smol::Task<T>>,
30}
31
32impl<T: 'static + Send> SmolAbortHandle<T> {
33    pub(crate) fn new_handle(task: smol::Task<T>) -> AbortHandleRef {
34        Box::new(Self { task: Some(task) })
35    }
36}
37
38impl<T: Send> AbortHandle for SmolAbortHandle<T> {
39    fn abort(mut self: Box<Self>) {
40        // Aborting a smol::Task is done by dropping it.
41        drop(self.task.take());
42    }
43}
44
45impl<T> Drop for SmolAbortHandle<T> {
46    fn drop(&mut self) {
47        // We prevent the task from being canceled by detaching it.
48        if let Some(task) = self.task.take() {
49            task.detach()
50        }
51    }
52}