tessera_ui_shard/
task_handles.rs

1use std::future::Future;
2
3use parking_lot::Mutex;
4use tokio::{sync::oneshot, task::JoinHandle};
5
6pub struct TaskHandle {
7    pub handle: JoinHandle<()>,
8    cancel: oneshot::Sender<()>,
9}
10
11pub struct TaskHandles {
12    tasks: Mutex<Vec<TaskHandle>>,
13}
14
15impl Default for TaskHandles {
16    fn default() -> Self {
17        Self::new()
18    }
19}
20
21impl Drop for TaskHandles {
22    fn drop(&mut self) {
23        self.cancel_all();
24    }
25}
26
27impl TaskHandles {
28    pub fn new() -> Self {
29        Self {
30            tasks: Mutex::new(Vec::new()),
31        }
32    }
33
34    pub fn spawn<F>(&self, fut: F)
35    where
36        F: Future<Output = ()> + Send + 'static,
37    {
38        let (tx, rx) = oneshot::channel();
39        let wrapped = async move {
40            tokio::select! {
41                _ = fut => {},
42                _ = rx => {},
43            }
44        };
45        let handle = crate::tokio_runtime::get().spawn(wrapped);
46        self.tasks.lock().push(TaskHandle { handle, cancel: tx });
47    }
48
49    pub fn cancel_all(&self) {
50        let mut tasks = self.tasks.lock();
51        for task in tasks.drain(..) {
52            let _ = task.cancel.send(());
53        }
54    }
55}