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}