wait_notify/
lib.rs

1//! rust_waitnotify
2use std::sync::{Arc, Condvar, Mutex};
3
4/// A WaitNotify waits for a notification to be sent.
5///
6/// # Examples
7/// ```
8/// use wait_notify::WaitNotify;
9/// use std::thread;
10///
11/// let wn = WaitNotify::default();
12/// let wn_clone = wn.clone();
13/// let handle = thread::spawn(move || {
14///    // do some work
15///    wn_clone.wait();
16///    // do some work
17///    });
18/// // do some work
19/// wn.notify();
20/// // do some work
21/// handle.join().unwrap();
22/// ```
23#[derive(Clone)]
24pub struct WaitNotify {
25    counter_cond: Arc<(Mutex<u64>, Condvar)>,
26}
27
28impl WaitNotify {
29    pub fn new() -> Self {
30        WaitNotify {
31            counter_cond: Arc::new((Mutex::new(0), Condvar::new())),
32        }
33    }
34    /// notify all thread waiting on this WaitNotify.
35    pub fn notify(&self) {
36        let (lock, cvar) = &*self.counter_cond;
37        let mut count = lock.lock().unwrap();
38        if *count == 0 {
39            *count = 1;
40            cvar.notify_all();
41        }
42    }
43    /// wait for notification.
44    pub fn wait(&self) {
45        let (lock, cvar) = &*self.counter_cond;
46        let mut count = lock.lock().unwrap();
47        while *count == 0 {
48            count = cvar.wait(count).unwrap();
49        }
50        *count = 0;
51    }
52}
53
54impl Default for WaitNotify {
55    fn default() -> Self {
56        WaitNotify::new()
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63    use std::thread;
64
65    #[test]
66    fn it_works() {
67        let wn = WaitNotify::default();
68        let wn_clone = wn.clone();
69        let handle = thread::spawn(move || {
70            wn_clone.wait();
71        });
72        wn.notify();
73        handle.join().unwrap();
74    }
75}