txrx/priv_sync/
mod.rs

1use std::hint::unreachable_unchecked;
2
3pub type MutexGuard<'a, T> = std::sync::MutexGuard<'a, T>;
4
5pub struct Mutex<T> {
6    inner: std::sync::Mutex<T>,
7}
8
9impl<T> Mutex<T> {
10    pub fn new(value: T) -> Self {
11        Self {
12            inner: std::sync::Mutex::new(value),
13        }
14    }
15
16    pub fn lock(&self) -> MutexGuard<T> {
17        self.inner.lock().unwrap()
18    }
19}
20
21pub struct Condvar {
22    inner: std::sync::Condvar,
23}
24
25impl Condvar {
26    pub fn new() -> Self {
27        Self {
28            inner: std::sync::Condvar::new(),
29        }
30    }
31
32    pub fn wait_while<'a, T, F>(&self, lock: MutexGuard<'a, T>, predicate: F) -> MutexGuard<'a, T>
33    where
34        F: FnMut(&mut T) -> bool,
35    {
36        self.inner.wait_while(lock, predicate).unwrap()
37    }
38
39    pub fn notify_one(&self) {
40        self.inner.notify_one();
41    }
42}
43
44pub struct AsyncValue<T> {
45    value: Mutex<Option<T>>,
46    cv: Condvar,
47}
48
49impl<T> AsyncValue<T> {
50    pub fn new() -> Self {
51        Self {
52            value: Mutex::new(None),
53            cv: Condvar::new(),
54        }
55    }
56
57    pub fn take(&self) -> T {
58        let lock = self.value.lock();
59        let mut lock = self.cv.wait_while(lock, |x| x.is_none());
60
61        if let Some(x) = lock.take() {
62            x
63        } else {
64            unsafe { unreachable_unchecked() }
65        }
66    }
67
68    pub fn set(&self, value: T) {
69        {
70            let mut lock = self.value.lock();
71            *lock = Some(value);
72        }
73        self.cv.notify_one();
74    }
75}