Skip to main content

chaud_hot/util/
latest.rs

1//! A utility for publishing some value from one thread, and making the most
2//! recently published value available to some other thread, with support
3//! for waiting for the next published value.
4
5use 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}