Skip to main content

leodos_libcfs/runtime/
scope.rs

1//! Scope - owns tasks and is itself a Future
2
3use core::future::Future;
4use core::pin::Pin;
5use core::task::Context;
6use core::task::Poll;
7
8use heapless::Vec;
9
10use crate::error::CfsError;
11use crate::runtime::task::Task;
12
13/// A scope that can spawn and manage multiple tasks
14#[must_use]
15pub struct Scope<'a, const MAX_TASK_SIZE: usize = 512, const MAX_TASKS: usize = 8> {
16    tasks: Vec<Task<'a, MAX_TASK_SIZE>, MAX_TASKS>,
17}
18
19impl<'a, const MAX_TASK_SIZE: usize, const MAX_TASKS: usize> Scope<'a, MAX_TASK_SIZE, MAX_TASKS> {
20    /// Create a new Scope
21    pub fn new() -> Self {
22        Self { tasks: Vec::new() }
23    }
24
25    /// Spawn a task into this scope
26    pub fn spawn<F>(&mut self, future: F) -> Result<(), CfsError>
27    where
28        F: Future<Output = Result<(), CfsError>> + 'a,
29    {
30        self.tasks
31            .push(Task::new(future))
32            .map_err(|_| CfsError::TaskPoolFull)
33    }
34}
35
36// Make Scope itself a Future that completes when all tasks complete
37impl<'a, const MAX_TASK_SIZE: usize, const MAX_TASKS: usize> Future
38    for Scope<'a, MAX_TASK_SIZE, MAX_TASKS>
39{
40    type Output = Result<(), CfsError>;
41
42    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
43        let mut all_done = true;
44
45        for task in self.tasks.iter_mut() {
46            if !task.is_done() {
47                match task.poll(cx) {
48                    Poll::Ready(Ok(())) => {
49                        task.cleanup();
50                    }
51                    Poll::Ready(Err(e)) => {
52                        return Poll::Ready(Err(e));
53                    }
54                    Poll::Pending => {
55                        all_done = false;
56                    }
57                }
58            }
59        }
60
61        if all_done && !self.tasks.is_empty() {
62            Poll::Ready(Ok(()))
63        } else {
64            Poll::Pending
65        }
66    }
67}