1use std::sync::{
2 atomic::{AtomicBool, Ordering},
3 Arc,
4};
5use tokio::sync::Notify;
6
7#[derive(Clone)]
9pub struct FutureBool {
10 notify_true: Arc<Notify>,
11 notify_false: Arc<Notify>,
12 inner: Arc<AtomicBool>,
13}
14
15impl FutureBool {
16 pub fn new(val: bool) -> Self {
18 Self {
19 notify_true: Arc::new(Notify::new()),
20 notify_false: Arc::new(Notify::new()),
21 inner: Arc::new(AtomicBool::new(val)),
22 }
23 }
24
25 pub fn set(&self) {
27 self.inner.store(true, Ordering::Release);
28 self.notify_true.notify_waiters();
29 }
30
31 pub fn unset(&self) {
33 self.inner.store(false, Ordering::Release);
34 self.notify_false.notify_waiters();
35 }
36
37 pub async fn wait_change(&self) -> bool {
39 let val = self.inner.load(Ordering::Acquire);
40 if val {
41 self.notify_false.notified().await;
42 } else {
43 self.notify_true.notified().await;
44 }
45 !val
46 }
47
48 pub async fn wait_true(&self) {
50 let val = self.inner.load(Ordering::Acquire);
51 if !val {
52 self.notify_true.notified().await;
53 }
54 }
55
56 pub async fn wait_false(&self) {
58 let val = self.inner.load(Ordering::Acquire);
59 if val {
60 self.notify_false.notified().await;
61 }
62 }
63}