simple_async/
executor.rs

1use std::{
2    future::Future,
3    rc::Rc,
4    sync::mpsc::{channel, Receiver, Sender},
5};
6
7use crate::task::Task;
8
9/// A struct that can be used to execute multiple async Tasks on a single thread.
10pub struct Executor {
11    task_queue: Receiver<Rc<Task>>,
12    task_sender: Sender<Rc<Task>>,
13}
14
15impl Executor {
16    pub fn new() -> Self {
17        let (task_sender, task_queue) = channel();
18        Self {
19            task_queue,
20            task_sender,
21        }
22    }
23
24    /// Enqueues a future into the executor.
25    /// It will be run to completion when [`run()`](Self::run()) is called.
26    pub fn spawn(&self, future: impl Future<Output = ()> + 'static) {
27        let task = Task::new(future, self.task_sender.clone());
28        self.task_sender.send(Rc::new(task)).unwrap();
29    }
30
31    /// Runs the executor until all tasks are completed.
32    /// After the last task is completed, the thread will exit.
33    pub fn run(self) -> ! {
34        // Drop our own copy of the task sender to ensure task_queue.recv() returns an error when the last Task has finished.
35        drop(self.task_sender);
36
37        loop {
38            let task = match self.task_queue.recv() {
39                Ok(task) => task,
40                Err(_) => std::process::exit(0),
41            };
42
43            let _ = task.poll();
44        }
45    }
46}
47
48impl Default for Executor {
49    fn default() -> Self {
50        Self::new()
51    }
52}