win_events/events/
manual_reset_pair.rs

1use std::collections::LinkedList;
2use std::error::Error;
3use std::sync::atomic::{AtomicBool, Ordering};
4use std::sync::{Arc, Mutex, MutexGuard};
5use std::time::Duration;
6
7use crate::events::event::{EventHandle, EventState};
8use crate::waiters::waiter::{Signaler, WaitInfo};
9use crate::{wait_one, Event};
10
11struct WaitPair {
12    set: LinkedList<WaitInfo>,
13    not: LinkedList<WaitInfo>,
14}
15
16struct Waiters {
17    pair: Mutex<WaitPair>,
18}
19
20impl Waiters {
21    fn new() -> Waiters {
22        let pair = WaitPair {
23            set: LinkedList::new(),
24            not: LinkedList::new(),
25        };
26
27        Waiters {
28            pair: Mutex::new(pair),
29        }
30    }
31
32    fn fire(&self) {
33        let pair = match self.pair.lock() {
34            Ok(pair) => pair,
35            Err(_) => return,
36        };
37
38        for info in &pair.set {
39            match info.signaler.fire(info.pos) {
40                _ => {}
41            }
42        }
43        for info in &pair.not {
44            match info.signaler.clear(info.pos) {
45                _ => {}
46            }
47        }
48    }
49
50    fn clear(&self) {
51        let pair = match self.pair.lock() {
52            Ok(pair) => pair,
53            Err(_) => return,
54        };
55
56        for info in &pair.not {
57            match info.signaler.fire(info.pos) {
58                _ => {}
59            }
60        }
61        for info in &pair.set {
62            match info.signaler.clear(info.pos) {
63                _ => {}
64            }
65        }
66    }
67
68    fn fire_not(&self) {
69        self.clear()
70    }
71
72    fn clear_not(&self) {
73        self.fire()
74    }
75
76    fn register_signaler_is_set(
77        &self,
78        pos: usize,
79        signaler: Arc<dyn Signaler>,
80    ) -> Result<(), Box<dyn Error>> {
81        let mut pair = match self.pair.lock() {
82            Ok(pair) => pair,
83            Err(error) => {
84                return Err(format!("Could not lock wait list: {}", error).into());
85            }
86        };
87
88        let info = WaitInfo { pos, signaler };
89        pair.set.push_back(info);
90
91        Ok(())
92    }
93
94    fn remove_signaler_is_set(&self, signaler: &Arc<dyn Signaler>) -> Result<(), Box<dyn Error>> {
95        let mut pair = match self.pair.lock() {
96            Ok(pair) => pair,
97            Err(error) => {
98                return Err(format!("Could not lock wait list: {}", error).into());
99            }
100        };
101
102        pair.set = {
103            let list = pair.set.clone();
104            let iter = list.into_iter();
105            let filtered = iter.filter(|info| Arc::ptr_eq(&info.signaler, signaler));
106            filtered.collect()
107        };
108        Ok(())
109    }
110
111    fn register_signaler_not_set(
112        &self,
113        pos: usize,
114        signaler: Arc<dyn Signaler>,
115    ) -> Result<(), Box<dyn Error>> {
116        let mut pair = match self.pair.lock() {
117            Ok(pair) => pair,
118            Err(error) => {
119                return Err(format!("Could not lock wait list: {}", error).into());
120            }
121        };
122
123        let info = WaitInfo { pos, signaler };
124        pair.not.push_back(info);
125
126        Ok(())
127    }
128
129    fn remove_signaler_not_set(&self, signaler: &Arc<dyn Signaler>) -> Result<(), Box<dyn Error>> {
130        let mut pair = match self.pair.lock() {
131            Ok(pair) => pair,
132            Err(error) => {
133                return Err(format!("Could not lock wait list: {}", error).into());
134            }
135        };
136
137        pair.not = {
138            let list = pair.set.clone();
139            let iter = list.into_iter();
140            let filtered = iter.filter(|info| Arc::ptr_eq(&info.signaler, signaler));
141            filtered.collect()
142        };
143        Ok(())
144    }
145}
146
147struct ManualResetEventPairInfo {
148    fired: AtomicBool,
149    waiters: Waiters,
150}
151
152impl ManualResetEventPairInfo {
153    fn new(init: bool) -> ManualResetEventPairInfo {
154        ManualResetEventPairInfo {
155            fired: AtomicBool::new(init),
156            waiters: Waiters::new(),
157        }
158    }
159}
160
161struct ManualResetEventSetInfo {
162    info: Arc<ManualResetEventPairInfo>,
163}
164
165impl EventState for ManualResetEventSetInfo {
166    fn is_set(&self) -> bool {
167        self.info.fired.load(Ordering::Relaxed)
168    }
169
170    fn set(&self) {
171        self.info.fired.store(true, Ordering::Relaxed);
172        self.info.waiters.fire();
173    }
174
175    fn clear(&self) {
176        self.info.fired.store(false, Ordering::Relaxed);
177        self.info.waiters.clear();
178    }
179
180    fn register_signaler(
181        &self,
182        pos: usize,
183        signaler: Arc<dyn Signaler>,
184    ) -> Result<(), Box<dyn Error>> {
185        if self.is_set() {
186            signaler.fire(pos)?
187        }
188        self.info.waiters.register_signaler_is_set(pos, signaler)
189    }
190
191    fn remove_signaler(&self, signaler: &Arc<dyn Signaler>) -> Result<(), Box<dyn Error>> {
192        self.info.waiters.remove_signaler_is_set(signaler)
193    }
194
195    fn wake_lock(&self) -> Result<Option<MutexGuard<()>>, Box<dyn Error>> {
196        Ok(None)
197    }
198
199    fn can_consume(&self) -> bool {
200        self.is_set()
201    }
202
203    fn consume(&self) {}
204}
205
206struct ManualResetEventNotSetInfo {
207    info: Arc<ManualResetEventPairInfo>,
208}
209
210impl EventState for ManualResetEventNotSetInfo {
211    fn is_set(&self) -> bool {
212        !self.info.fired.load(Ordering::Relaxed)
213    }
214
215    fn set(&self) {
216        self.info.fired.store(false, Ordering::Relaxed);
217        self.info.waiters.fire_not()
218    }
219
220    fn clear(&self) {
221        self.info.fired.store(true, Ordering::Relaxed);
222        self.info.waiters.clear_not();
223    }
224
225    fn register_signaler(
226        &self,
227        pos: usize,
228        signaler: Arc<dyn Signaler>,
229    ) -> Result<(), Box<dyn Error>> {
230        if self.is_set() {
231            signaler.fire(pos)?
232        }
233        self.info.waiters.register_signaler_not_set(pos, signaler)
234    }
235
236    fn remove_signaler(&self, signaler: &Arc<dyn Signaler>) -> Result<(), Box<dyn Error>> {
237        self.info.waiters.remove_signaler_not_set(signaler)
238    }
239
240    fn wake_lock(&self) -> Result<Option<MutexGuard<()>>, Box<dyn Error>> {
241        Ok(None)
242    }
243
244    fn can_consume(&self) -> bool {
245        self.is_set()
246    }
247
248    fn consume(&self) {}
249}
250
251/// A ManualResetEventPair
252///
253/// An event represents a boolean condition that can be waited on until signaled. This allows a
254/// thread to block and wait for another thread to set the event. Until the event is manually reset
255/// waiting will return immediately.
256///
257/// # Examples
258///
259/// ```
260/// use std::thread;
261/// use std::time::Duration;
262/// use win_events::{Event, ManualResetEventPair};
263///
264/// let evt_started = ManualResetEventPair::new(false);
265/// let evt_started2 = evt_started.clone();
266///
267/// // spawn a thread and set the cloned event
268/// thread::spawn(move|| {
269///     evt_started2.set();
270/// });
271///
272/// // Wait for the started event
273/// evt_started.wait(Duration::from_millis(100)).unwrap();
274/// ```
275#[derive(Clone)]
276pub struct ManualResetEventPair {
277    pair: Arc<ManualResetEventPairInfo>,
278    info: Arc<EventHandle>,
279}
280
281impl ManualResetEventPair {
282    /// Creates a new ManualResetEventPair which can create events to wait on
283    /// internally on both set and not set
284    ///
285    /// # Examples
286    ///
287    /// ```
288    /// use win_events::ManualResetEventPair;
289    ///
290    /// let evt = ManualResetEventPair::new(false);
291    /// ```
292    pub fn new(init: bool) -> ManualResetEventPair {
293        let pair = Arc::new(ManualResetEventPairInfo::new(init));
294        let state: Box<dyn EventState> = Box::new(ManualResetEventSetInfo {
295            info: Arc::clone(&pair),
296        });
297        let info = Arc::new(EventHandle::new(state));
298        ManualResetEventPair { pair, info }
299    }
300
301    /// Gets the current state of the event.
302    ///
303    /// # Examples
304    ///
305    /// ```
306    /// use win_events::ManualResetEventPair;
307    ///
308    /// let evt = ManualResetEventPair::new(true);
309    /// assert!(evt.is_set())
310    ///  ```
311    pub fn is_set(&self) -> bool {
312        self.info.is_set()
313    }
314
315    /// Sets the event and fires a signal to any threads waiting on the event.
316    ///
317    /// # Examples
318    ///
319    /// ```
320    /// use win_events::ManualResetEventPair;
321    ///
322    /// let evt = ManualResetEventPair::new(false);
323    /// evt.set();
324    /// assert!(evt.is_set())
325    /// ```
326    pub fn set(&self) {
327        self.info.set()
328    }
329
330    /// Sets the even, causing any waiting threads to receive a signal.
331    ///
332    /// # Examples
333    ///
334    /// ```
335    /// use win_events::ManualResetEventPair;
336    ///
337    /// let evt = ManualResetEventPair::new(false);
338    /// evt.clear();
339    /// assert!(!evt.is_set())
340    /// ```
341    pub fn clear(&self) {
342        self.info.clear()
343    }
344    /// Creates a new ManualResetEventPair and initialized the value.
345    ///
346    /// # Examples
347    ///
348    /// ```
349    /// use std::thread::{sleep, spawn};
350    /// use std::time::Duration;
351    /// use win_events::ManualResetEventPair;
352    ///
353    /// let evt = ManualResetEventPair::new(false);
354    /// let evt_inner = evt.clone();
355    ///
356    /// let worker = spawn(move || {
357    ///    sleep(Duration::from_millis(3));
358    ///    evt_inner.set()
359    /// });
360    ///
361    /// let wait_result = evt.wait(Duration::from_millis(100)).unwrap();
362    /// assert!(wait_result);
363    /// worker.join();
364    /// ```
365    pub fn wait(&self, dur: Duration) -> Result<bool, Box<dyn Error>> {
366        wait_one(self, dur)
367    }
368
369    /// Creates an event that will wait on the state to be set
370    ///
371    /// # Examples
372    ///
373    /// ```
374    /// use std::thread::{sleep, spawn};
375    /// use std::time::Duration;
376    /// use win_events::ManualResetEventPair;
377    ///
378    /// let evt = ManualResetEventPair::new(false);
379    /// let event_set = evt.event_set();
380    ///
381    /// let worker = spawn(move || {
382    ///    sleep(Duration::from_millis(3));
383    ///    evt.set()
384    /// });
385    ///
386    /// let wait_result = event_set.wait(Duration::from_millis(100)).unwrap();
387    /// assert!(wait_result);
388    /// worker.join();
389    /// ```
390    pub fn event_set(&self) -> ManualResetEventPair {
391        let pair = Arc::clone(&self.pair);
392        let state: Box<dyn EventState> = Box::new(ManualResetEventSetInfo {
393            info: Arc::clone(&pair),
394        });
395        let info = Arc::new(EventHandle::new(state));
396        ManualResetEventPair { pair, info }
397    }
398
399    /// Creates an event that will wait on the state to be set
400    ///
401    /// # Examples
402    ///
403    /// ```
404    /// use std::thread::{sleep, spawn};
405    /// use std::time::Duration;
406    /// use win_events::ManualResetEventPair;
407    ///
408    /// let evt = ManualResetEventPair::new(true);
409    /// let event_not_set = evt.event_not_set();
410    ///
411    /// let worker = spawn(move || {
412    ///    sleep(Duration::from_millis(3));
413    ///    evt.clear()
414    /// });
415    ///
416    /// let wait_result = event_not_set.wait(Duration::from_millis(100)).unwrap();
417    /// assert!(wait_result);
418    /// worker.join();
419    /// ```
420    pub fn event_not_set(&self) -> ManualResetEventPair {
421        let pair = Arc::clone(&self.pair);
422        let state: Box<dyn EventState> = Box::new(ManualResetEventNotSetInfo {
423            info: Arc::clone(&pair),
424        });
425        let info = Arc::new(EventHandle::new(state));
426        ManualResetEventPair { pair, info }
427    }
428}
429
430impl Event for ManualResetEventPair {
431    fn handle(&self) -> &Arc<EventHandle> {
432        &self.info
433    }
434}