Skip to main content

async_rs/implementors/
async_global_executor.rs

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