use std::cell::Cell;
use std::future::Future;
use std::rc::Rc;
use async_task::{Runnable, Task};
thread_local! {
static QUEUE: (flume::Sender<Runnable>, flume::Receiver<Runnable>) = flume::unbounded();
}
fn spawn<F, T>(future: F) -> Task<T>
where
F: Future<Output = T> + 'static,
T: 'static,
{
let schedule = |runnable| QUEUE.with(|(s, _)| s.send(runnable).unwrap());
let (runnable, task) = async_task::spawn_local(future, schedule);
runnable.schedule();
task
}
fn run<F, T>(future: F) -> T
where
F: Future<Output = T> + 'static,
T: 'static,
{
let (s, r) = flume::unbounded();
spawn(async move { drop(s.send(future.await)) }).detach();
loop {
if let Ok(val) = r.try_recv() {
return val;
}
QUEUE.with(|(_, r)| r.recv().unwrap().run());
}
}
fn main() {
let val = Rc::new(Cell::new(0));
run({
let val = val.clone();
async move {
let task = spawn({
let val = val.clone();
async move {
val.set(dbg!(val.get()) + 1);
}
});
val.set(dbg!(val.get()) + 1);
task.await;
}
});
dbg!(val.get());
}