1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Condvar, Mutex};
#[derive(Debug)]
#[allow(clippy::mutex_atomic)]
pub struct Sleepers {
sleep: Mutex<usize>,
wake: Condvar,
notified: AtomicBool,
}
#[allow(clippy::mutex_atomic)]
impl Default for Sleepers {
fn default() -> Self {
Self {
sleep: Mutex::new(0),
wake: Condvar::new(),
notified: AtomicBool::new(false),
}
}
}
#[allow(clippy::mutex_atomic)]
impl Sleepers {
pub fn new() -> Self {
Self::default()
}
pub fn wait(&self) {
let mut sleep = self.sleep.lock().unwrap();
if !self.notified.swap(false, Ordering::SeqCst) {
*sleep += 1;
std::mem::drop(self.wake.wait(sleep).unwrap());
}
}
pub fn notify_one(&self) {
if !self.notified.load(Ordering::SeqCst) {
let mut sleep = self.sleep.lock().unwrap();
if *sleep > 0 {
*sleep -= 1;
self.wake.notify_one();
} else {
self.notified.store(true, Ordering::SeqCst);
}
}
}
}