waitable/lib.rs
1//! This crate consists of a single struct, [`Waitable`] that holds a value
2//! which can be get, set and waited upon.
3
4use parking_lot::{Condvar, Mutex};
5
6/// A waitable variable
7///
8/// This struct is essentially the `Mutex` and `Condvar` tuple documented in
9/// [`parking_lot::Condvar`], presented in an easy-to-use form.
10///
11/// [`parking_lot::Condvar`]: `parking_lot::Condvar#examples`
12#[derive(Debug)]
13pub struct Waitable<T> {
14 value: Mutex<T>,
15 condvar: Condvar,
16}
17
18impl<T> Waitable<T> {
19 /// Create a new waitable variable
20 ///
21 /// # Examples
22 ///
23 /// ```
24 /// use waitable::Waitable;
25 ///
26 /// let w = Waitable::new(0);
27 /// ```
28 pub fn new(value: T) -> Self {
29 Self {
30 value: Mutex::new(value),
31 condvar: Condvar::new(),
32 }
33 }
34
35 /// Sets the value of the waitable
36 ///
37 /// This function wakes up ([`notify_all`]) all waiters so that they may
38 /// check their waiting conditions and return if appropriate.
39 ///
40 /// [`notify_all`]: parking_lot::Condvar::notify_all
41 pub fn set(&self, value: T) {
42 let mut vg = self.value.lock();
43 *vg = value;
44 self.condvar.notify_all();
45 }
46
47 /// Waits until a condition is satisfied
48 ///
49 /// This function will block the current thread until the predicate
50 /// specified by `cond` returns `true` on the current value of the
51 /// Waitable.
52 ///
53 /// If `cond` initially returns `true`, no blocking is done.
54 pub fn wait_cond<F: Fn(&T) -> bool>(&self, cond: F) {
55 let mut vg = self.value.lock();
56 while !cond(&*vg) {
57 self.condvar.wait(&mut vg);
58 }
59 }
60}
61
62impl<T: Copy> Waitable<T> {
63 /// Gets the value in the waitable
64 pub fn get(&self) -> T {
65 *self.value.lock()
66 }
67}
68
69impl<T: PartialEq> Waitable<T> {
70 /// Waits until the value of the waitable equals a certain value
71 ///
72 /// This function is essentially equivalent to
73 /// `wait_cond(|val| val == value)`
74 pub fn wait(&self, value: &T) {
75 let mut vg = self.value.lock();
76 while &*vg != value {
77 self.condvar.wait(&mut vg);
78 }
79 }
80}
81
82impl<T: Default> Default for Waitable<T> {
83 /// Constructs a waitable containing the default value of the inner type
84 fn default() -> Self {
85 Self::new(T::default())
86 }
87}