async_rs/implementors/
async_global_executor.rs

1//! async-global-executor implementation of async runtime definition traits
2
3use crate::{
4    Runtime,
5    traits::Executor,
6    util::{RuntimeParts, Task},
7};
8use std::future::Future;
9
10use task::AGETask;
11
12#[cfg(feature = "async-io")]
13use crate::AsyncIO;
14
15/// Type alias for the async-global-executor runtime
16#[cfg(feature = "async-io")]
17pub type AGERuntime = Runtime<RuntimeParts<AsyncGlobalExecutor, AsyncIO>>;
18
19#[cfg(feature = "async-io")]
20impl AGERuntime {
21    /// Create a new SmolRuntime
22    pub fn async_global_executor() -> Self {
23        Self::new(RuntimeParts::new(AsyncGlobalExecutor, AsyncIO))
24    }
25}
26
27/// Dummy object implementing executor common interfaces on top of async-global-executor
28#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
29pub struct AsyncGlobalExecutor;
30
31impl Executor for AsyncGlobalExecutor {
32    type Task<T: Send + 'static> = AGETask<T>;
33
34    fn block_on<T, F: Future<Output = T>>(&self, f: F) -> T {
35        async_global_executor::block_on(f)
36    }
37
38    fn spawn<T: Send + 'static, F: Future<Output = T> + Send + 'static>(
39        &self,
40        f: F,
41    ) -> Task<Self::Task<T>> {
42        AGETask(Some(async_global_executor::spawn(f))).into()
43    }
44
45    fn spawn_blocking<T: Send + 'static, F: FnOnce() -> T + Send + 'static>(
46        &self,
47        f: F,
48    ) -> Task<Self::Task<T>> {
49        AGETask(Some(async_global_executor::spawn_blocking(f))).into()
50    }
51}
52
53mod task {
54    use crate::util::TaskImpl;
55    use async_trait::async_trait;
56    use std::{
57        future::Future,
58        pin::Pin,
59        task::{Context, Poll},
60    };
61
62    /// An async-global-executor task
63    #[derive(Debug)]
64    pub struct AGETask<T: Send + 'static>(pub(super) Option<async_global_executor::Task<T>>);
65
66    #[async_trait]
67    impl<T: Send + 'static> TaskImpl for AGETask<T> {
68        async fn cancel(&mut self) -> Option<T> {
69            self.0.take()?.cancel().await
70        }
71
72        fn detach(&mut self) {
73            if let Some(task) = self.0.take() {
74                task.detach();
75            }
76        }
77    }
78
79    impl<T: Send + 'static> Future for AGETask<T> {
80        type Output = T;
81
82        fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
83            Pin::new(self.0.as_mut().expect("task canceled")).poll(cx)
84        }
85    }
86}
87
88#[cfg(test)]
89mod tests {
90    use super::*;
91
92    #[test]
93    fn auto_traits() {
94        use crate::util::test::*;
95        #[cfg(feature = "async-io")]
96        let runtime = Runtime::async_global_executor();
97        #[cfg(not(feature = "async-io"))]
98        let runtime = AsyncGlobalExecutor;
99        assert_send(&runtime);
100        assert_sync(&runtime);
101        assert_clone(&runtime);
102    }
103}