#![cfg(feature = "async-executor")]
use std::{
future::Future,
pin::Pin,
sync::{Arc, Mutex},
};
struct TestExecutor {
tasks: Mutex<Vec<Pin<Box<dyn Future<Output = ()> + Send + 'static>>>>,
}
impl TestExecutor {
fn new() -> Self {
TestExecutor {
tasks: Mutex::new(Vec::new()),
}
}
fn spawn<F>(&self, future: F)
where
F: Future<Output = ()> + Send + 'static,
{
self.tasks.lock().unwrap().push(Box::pin(future));
}
fn run_all(&self) {
let tasks = self.tasks.lock().unwrap().drain(..).collect::<Vec<_>>();
for mut task in tasks {
futures::executor::block_on(async {
unsafe {
let task_mut = Pin::new_unchecked(&mut task);
let _ = std::future::Future::poll(
task_mut,
&mut std::task::Context::from_waker(
futures::task::noop_waker_ref(),
),
);
}
});
}
}
}
#[test]
fn test_async_executor() {
let executor = Arc::new(TestExecutor::new());
let executor_clone = executor.clone();
let spawner = move |future| {
executor_clone.spawn(future);
};
let counter = Arc::new(Mutex::new(0));
let counter_clone = counter.clone();
spawner(async move {
*counter_clone.lock().unwrap() += 1;
});
executor.run_all();
assert_eq!(*counter.lock().unwrap(), 1);
}