waitout/
lib.rs

1//! waitgroup provides an interface for awaiting the completion of multiple asynchronous tasks
2
3use std::sync::{Condvar, Mutex};
4
5/// A waitgroup waits for a collection of tasks to complete.
6/// It keeps track of tasks via shared counter
7pub struct WaitGroup {
8    cvar: Condvar,
9    count: Mutex<usize>,
10}
11
12impl Default for WaitGroup {
13    fn default() -> WaitGroup {
14        WaitGroup::new(0)
15    }
16}
17
18impl WaitGroup {
19    /// creates a new wait group instance
20    pub fn new(n: usize) -> WaitGroup {
21        WaitGroup {
22            cvar: Condvar::new(),
23            count: Mutex::new(n),
24        }
25    }
26
27    /// adds `delta` to internal counter
28    pub fn add(&self, delta: usize) {
29        let mut count = self.count.lock().unwrap();
30        *count += delta;
31        self.notify_if_empty(*count)
32    }
33
34    /// subtracts 1 from internal counter
35    pub fn done(&self) {
36        let mut count = self.count.lock().unwrap();
37        *count -= 1;
38        self.notify_if_empty(*count)
39    }
40
41    fn notify_if_empty(&self, count: usize) {
42        if count <= 0 {
43            self.cvar.notify_all();
44        }
45    }
46
47    /// blocks the current thread until wait group is complete
48    pub fn wait(&self) {
49        let mut count = self.count.lock().unwrap();
50        while *count > 0 {
51            count = self.cvar.wait(count).unwrap();
52        }
53    }
54}
55
56#[test]
57fn it_works() {}