Skip to content

Commit 0b6ffdf

Browse files
committed
add async-global-executor implementation of Executor
1 parent b8348cc commit 0b6ffdf

File tree

4 files changed

+105
-2
lines changed

4 files changed

+105
-2
lines changed

Cargo.lock

Lines changed: 17 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,19 @@ rust-version = "1.85.0"
1414

1515
[features]
1616
default = ["tokio"]
17+
async-global-executor = ["dep:async-global-executor"]
1718
smol = ["dep:smol"]
1819
tokio = ["dep:tokio"]
1920

2021
[dependencies]
2122
async-trait = "^0.1.89"
2223

24+
[dependencies.async-global-executor]
25+
version = "^3.1"
26+
optional = true
27+
default-features = false
28+
features = ["async-io"]
29+
2330
[dependencies.smol]
2431
version = "^2.0"
2532
optional = true

src/async_global_executor.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//! async-global-executor implementation of async runtime definition traits
2+
3+
use crate::executor::{Executor, Task};
4+
use alloc::boxed::Box;
5+
use async_trait::async_trait;
6+
use core::{
7+
future::Future,
8+
pin::Pin,
9+
task::{Context, Poll},
10+
};
11+
12+
/// Dummy object implementing executor-trait common interfaces on top of async-global-executor
13+
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
14+
pub struct AsyncGlobalExecutor;
15+
16+
struct AGETask<T>(Option<async_global_executor::Task<T>>);
17+
18+
impl Executor for AsyncGlobalExecutor {
19+
fn block_on<T>(&self, f: Pin<Box<dyn Future<Output = T>>>) -> T {
20+
async_global_executor::block_on(f)
21+
}
22+
23+
fn spawn<T: Send + 'static>(
24+
&self,
25+
f: impl Future<Output = T> + Send + 'static,
26+
) -> impl Task<T> {
27+
AGETask(Some(async_global_executor::spawn(f)))
28+
}
29+
30+
fn spawn_blocking<F: FnOnce() -> T + Send + 'static, T: Send + 'static>(
31+
&self,
32+
f: F,
33+
) -> impl Task<T> {
34+
AGETask(Some(async_global_executor::spawn_blocking(f)))
35+
}
36+
}
37+
38+
#[async_trait(?Send)]
39+
impl<T> Task<T> for AGETask<T> {
40+
async fn cancel(&mut self) -> Option<T> {
41+
self.0.take()?.cancel().await
42+
}
43+
}
44+
45+
impl<T> Drop for AGETask<T> {
46+
fn drop(&mut self) {
47+
if let Some(task) = self.0.take() {
48+
task.detach();
49+
}
50+
}
51+
}
52+
53+
impl<T> Future for AGETask<T> {
54+
type Output = T;
55+
56+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
57+
Pin::new(self.0.as_mut().expect("task canceled")).poll(cx)
58+
}
59+
}
60+
61+
#[cfg(test)]
62+
mod tests {
63+
use super::*;
64+
use alloc::string::String;
65+
66+
#[test]
67+
fn dyn_compat() {
68+
struct Test {
69+
_executor: Box<dyn Executor>,
70+
_task: Box<dyn Task<String>>,
71+
}
72+
73+
let _ = Test {
74+
_executor: Box::new(AsyncGlobalExecutor::default()),
75+
_task: Box::new(AGETask(None)),
76+
};
77+
}
78+
}

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ extern crate core;
99

1010
pub mod executor;
1111

12+
#[cfg(feature = "async-global-executor")]
13+
pub mod async_global_executor;
14+
1215
#[cfg(feature = "smol")]
1316
pub mod smol;
1417

0 commit comments

Comments
 (0)