blob: 9db721596aeae2e4f3d5bb8b513740d53af83c11 [file] [log] [blame]
Stjepan Glavina1479e862019-08-12 20:18:51 +02001//! A simple single-threaded executor.
2
Stjepan Glavina1479e862019-08-12 20:18:51 +02003use std::future::Future;
4use std::panic::catch_unwind;
5use std::thread;
6
7use crossbeam::channel::{unbounded, Sender};
8use futures::executor;
9use lazy_static::lazy_static;
10
Stjepan Glavinafcfa4ab2019-11-25 18:39:17 +010011type Task = async_task::Task<()>;
12type JoinHandle<T> = async_task::JoinHandle<T, ()>;
13
Stjepan Glavina1479e862019-08-12 20:18:51 +020014/// Spawns a future on the executor.
Stjepan Glavinafcfa4ab2019-11-25 18:39:17 +010015fn spawn<F, R>(future: F) -> JoinHandle<R>
Stjepan Glavina1479e862019-08-12 20:18:51 +020016where
17 F: Future<Output = R> + Send + 'static,
18 R: Send + 'static,
19{
20 lazy_static! {
21 // A channel that holds scheduled tasks.
Stjepan Glavinafcfa4ab2019-11-25 18:39:17 +010022 static ref QUEUE: Sender<Task> = {
23 let (sender, receiver) = unbounded::<Task>();
Stjepan Glavina1479e862019-08-12 20:18:51 +020024
25 // Start the executor thread.
26 thread::spawn(|| {
27 for task in receiver {
28 // Ignore panics for simplicity.
29 let _ignore_panic = catch_unwind(|| task.run());
30 }
31 });
32
33 sender
34 };
35 }
36
37 // Create a task that is scheduled by sending itself into the channel.
38 let schedule = |t| QUEUE.send(t).unwrap();
39 let (task, handle) = async_task::spawn(future, schedule, ());
40
41 // Schedule the task by sending it into the channel.
42 task.schedule();
43
44 handle
45}
46
47fn main() {
48 // Spawn a future and await its result.
49 let handle = spawn(async {
50 println!("Hello, world!");
51 });
52 executor::block_on(handle);
53}