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