Skip to main content

zero_pool/
task_future.rs

1use crate::atomic_latch::AtomicLatch;
2use std::time::Duration;
3
4/// A future that tracks completion of submitted tasks
5///
6/// `TaskFuture` provides both blocking and non-blocking ways to wait for
7/// task completion. Tasks can be checked for completion, waited on
8/// indefinitely, or waited on with a timeout.
9///
10/// `TaskFuture` is cheaply cloneable. However, it captures the thread handle
11/// of the thread that created it.
12///
13/// If sharing the future with other threads, `is_complete()` is safe to call
14/// from anywhere.
15///
16/// **Important:** `wait()` and `wait_timeout()` **must** be called from the
17/// same thread that created the `TaskFuture`. Calling these methods from a
18/// different thread will panic in debug builds and may cause the calling thread
19/// to hang indefinitely in release builds.
20///
21#[derive(Clone)]
22pub struct TaskFuture(AtomicLatch);
23
24impl TaskFuture {
25    pub(crate) fn new(task_count: usize) -> Self {
26        TaskFuture(AtomicLatch::new(task_count))
27    }
28
29    /// Check if all tasks are complete without blocking
30    ///
31    /// Returns `true` if all tasks have finished execution.
32    /// This is a non-blocking operation using atomic loads.
33    pub fn is_complete(&self) -> bool {
34        self.0.is_complete()
35    }
36
37    /// Wait for all tasks to complete
38    ///
39    /// First checks completion with an atomic load; if incomplete, parks the thread that sent the work.
40    pub fn wait(self) {
41        self.0.wait();
42    }
43
44    /// Wait for all tasks to complete with a timeout
45    ///
46    /// First checks completion with an atomic load; if incomplete, parks the thread that sent the work.
47    /// Returns `true` if all tasks completed within the timeout,
48    /// `false` if the timeout was reached first.
49    pub fn wait_timeout(self, timeout: Duration) -> bool {
50        self.0.wait_timeout(timeout)
51    }
52
53    // completes multiple tasks, decrements counter and notifies if all done
54    pub(crate) fn complete_many(&self, count: usize) -> bool {
55        self.0.decrement(count)
56    }
57}