win_events/waiters/
wait_one.rs1use std::error::Error;
2use std::sync::Arc;
3use std::time::{Duration, SystemTime};
4
5use crate::events::event::{try_consume_one, AutoUnregister};
6use crate::Event;
7
8use super::waiter::{Signaler, Waiter};
9
10type WaitOne = Waiter<bool>;
11
12impl Signaler for WaitOne {
13 fn fire(&self, pos: usize) -> Result<(), Box<dyn Error>> {
14 let lock = self.lock();
15 let mut data = match lock {
16 Ok(data) => data,
17 Err(error) => {
18 return Err(format!("Failed to fire event: {}", error).into());
19 }
20 };
21
22 *data = pos == 0;
23 self.condvar.notify_all();
24 Ok(())
25 }
26
27 fn clear(&self, _: usize) -> Result<(), Box<dyn Error>> {
28 Ok(())
29 }
30}
31
32pub fn wait_one(event: &dyn Event, dur: Duration) -> Result<bool, Box<dyn Error>> {
63 if event.handle().is_set() && try_consume_one(event)? {
65 return Ok(true);
66 }
67
68 let signaler = Arc::new(WaitOne::new(false));
69
70 let registered = AutoUnregister::register_signaler(Arc::<WaitOne>::clone(&signaler), 0, event)?;
73
74 let start = SystemTime::now();
76 let mut dur_remaining = dur;
77 let result = loop {
78 let data = signaler.lock()?;
79 let lock_result = signaler
80 .condvar
81 .wait_timeout_while(data, dur_remaining, |fired| !*fired);
82
83 let (mut fired, timeout) = match lock_result {
84 Ok(result) => result,
85 Err(error) => break Err(format!("Wait failed: {}", error).into()),
86 };
87
88 if timeout.timed_out() {
90 break Ok(false);
91 }
92
93 if event.handle().can_consume() && try_consume_one(event)? {
95 break Ok(true);
96 }
97
98 *fired = false;
100
101 let result = start.elapsed();
103 match result {
104 Ok(elapsed) => dur_remaining = dur - elapsed,
105 Err(_) => {
107 break Ok(false);
108 }
109 }
110 };
111
112 drop(registered);
114 result
115}