async_rs/implementors/
async_global_executor.rs1use crate::{Executor, Runtime, RuntimeParts, Task};
4use async_trait::async_trait;
5use std::{
6 future::Future,
7 pin::Pin,
8 task::{Context, Poll},
9};
10
11#[cfg(feature = "async-io")]
12use crate::AsyncIO;
13
14#[cfg(feature = "async-io")]
16pub type AGERuntime = Runtime<RuntimeParts<AsyncGlobalExecutor, AsyncIO>>;
17
18#[cfg(feature = "async-io")]
19impl AGERuntime {
20 pub fn async_global_executor() -> Self {
22 Self::new(RuntimeParts::new(AsyncGlobalExecutor, AsyncIO))
23 }
24}
25
26#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
28pub struct AsyncGlobalExecutor;
29
30struct AGETask<T: Send>(Option<async_global_executor::Task<T>>);
31
32impl Executor for AsyncGlobalExecutor {
33 fn block_on<T, F: Future<Output = T>>(&self, f: F) -> T {
34 async_global_executor::block_on(f)
35 }
36
37 fn spawn<T: Send + 'static>(
38 &self,
39 f: impl Future<Output = T> + Send + 'static,
40 ) -> impl Task<T> {
41 AGETask(Some(async_global_executor::spawn(f)))
42 }
43
44 fn spawn_blocking<F: FnOnce() -> T + Send + 'static, T: Send + 'static>(
45 &self,
46 f: F,
47 ) -> impl Task<T> {
48 AGETask(Some(async_global_executor::spawn_blocking(f)))
49 }
50}
51
52#[async_trait(?Send)]
53impl<T: Send> Task<T> for AGETask<T> {
54 async fn cancel(&mut self) -> Option<T> {
55 self.0.take()?.cancel().await
56 }
57}
58
59impl<T: Send> Drop for AGETask<T> {
60 fn drop(&mut self) {
61 if let Some(task) = self.0.take() {
62 task.detach();
63 }
64 }
65}
66
67impl<T: Send> Future for AGETask<T> {
68 type Output = T;
69
70 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
71 Pin::new(self.0.as_mut().expect("task canceled")).poll(cx)
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn dyn_compat() {
81 struct Test {
82 _executor: Box<dyn Executor>,
83 _task: Box<dyn Task<String>>,
84 }
85
86 let _ = Test {
87 _executor: Box::new(AsyncGlobalExecutor),
88 _task: Box::new(AGETask(None)),
89 };
90 }
91}