1use parking_lot::{Condvar, Mutex};
6use std::sync::Arc;
7
8struct Inner<T> {
9 val: Mutex<T>,
10 cond: Condvar,
11}
12
13pub struct LatestPublisher<T> {
14 inner: Arc<Inner<T>>,
15}
16
17pub struct LatestReader<T> {
18 inner: Arc<Inner<T>>,
19 latest: T,
20}
21
22pub fn make_latest<T: Copy>(initial: T) -> (LatestPublisher<T>, LatestReader<T>) {
23 let i = Arc::new(Inner { val: Mutex::new(initial), cond: Condvar::new() });
24
25 (
26 LatestPublisher { inner: i.clone() },
27 LatestReader { inner: i, latest: initial },
28 )
29}
30
31impl<T> LatestPublisher<T> {
32 pub fn publish(&mut self, val: T) {
33 *self.inner.val.lock() = val;
34 self.inner.cond.notify_one();
35 }
36}
37
38impl<T: Copy + PartialEq> LatestReader<T> {
39 pub fn wait(&mut self) -> T {
40 let mut guard = self.inner.val.lock();
41
42 self.inner
43 .cond
44 .wait_while(&mut guard, |val| *val == self.latest);
45
46 self.latest = *guard;
47 self.latest
48 }
49
50 pub fn check(&mut self) -> Option<T> {
51 let guard = self.inner.val.lock();
52
53 match *guard == self.latest {
54 true => None,
55 false => {
56 self.latest = *guard;
57 Some(self.latest)
58 }
59 }
60 }
61}