blob: 4af5a029c97ab9c55179ce1ed1d79a45ada42c97 [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
11/// Spawns a future on the executor.
12fn spawn<F, R>(future: F) -> async_task::JoinHandle<R, ()>
13where
14 F: Future<Output = R> + Send + 'static,
15 R: Send + 'static,
16{
17 lazy_static! {
18 // A channel that holds scheduled tasks.
19 static ref QUEUE: Sender<async_task::Task<()>> = {
20 let (sender, receiver) = unbounded::<async_task::Task<()>>();
21
22 // Start the executor thread.
23 thread::spawn(|| {
24 for task in receiver {
25 // Ignore panics for simplicity.
26 let _ignore_panic = catch_unwind(|| task.run());
27 }
28 });
29
30 sender
31 };
32 }
33
34 // Create a task that is scheduled by sending itself into the channel.
35 let schedule = |t| QUEUE.send(t).unwrap();
36 let (task, handle) = async_task::spawn(future, schedule, ());
37
38 // Schedule the task by sending it into the channel.
39 task.schedule();
40
41 handle
42}
43
44fn main() {
45 // Spawn a future and await its result.
46 let handle = spawn(async {
47 println!("Hello, world!");
48 });
49 executor::block_on(handle);
50}