win_events/events/
auto_reset.rs

1use std::error::Error;
2use std::sync::atomic::{AtomicBool, Ordering};
3use std::sync::{Arc, Mutex, MutexGuard};
4use std::time::Duration;
5
6use crate::events::event::{EventHandle, EventState};
7use crate::waiters::waiter::{Signaler, WaitList};
8use crate::{wait_one, Event};
9
10struct AutoResetEventInfo {
11    fired: AtomicBool,
12    waiters: WaitList,
13    wake_lock: Mutex<()>,
14}
15
16impl AutoResetEventInfo {
17    fn new(init: bool) -> AutoResetEventInfo {
18        AutoResetEventInfo {
19            fired: AtomicBool::new(init),
20            waiters: WaitList::new(),
21            wake_lock: Mutex::new(()),
22        }
23    }
24}
25
26impl AutoResetEventInfo {
27    fn set_value(&self, value: bool) {
28        self.fired.store(value, Ordering::Relaxed);
29        // If there are waiters, fire a signal
30        self.waiters.fire()
31    }
32}
33
34impl EventState for AutoResetEventInfo {
35    fn is_set(&self) -> bool {
36        self.fired.load(Ordering::Relaxed)
37    }
38
39    fn set(&self) {
40        self.set_value(true)
41    }
42
43    fn clear(&self) {
44        self.set_value(false)
45    }
46
47    fn register_signaler(
48        &self,
49        pos: usize,
50        signaler: Arc<dyn Signaler>,
51    ) -> Result<(), Box<dyn Error>> {
52        if self.is_set() {
53            signaler.fire(pos)?;
54        }
55        self.waiters.register_signaler(pos, signaler)
56    }
57
58    fn remove_signaler(&self, signaler: &Arc<dyn Signaler>) -> Result<(), Box<dyn Error>> {
59        self.waiters.remove_signaler(signaler)
60    }
61
62    fn wake_lock(&self) -> Result<Option<MutexGuard<()>>, Box<dyn Error>> {
63        let result = self.wake_lock.lock();
64
65        match result {
66            Ok(guard) => Ok(Some(guard)),
67            Err(error) => Err(format!("Could not lock wake mutex: {}", error).into()),
68        }
69    }
70
71    fn can_consume(&self) -> bool {
72        self.fired.load(Ordering::Relaxed)
73    }
74
75    fn consume(&self) {
76        self.fired.store(false, Ordering::Relaxed)
77    }
78}
79
80/// A AutoResetEvent
81///
82/// An event represents a boolean condition that can be waited on until signaled. This allows a
83/// thread to block and wait for another thread to set the event. A waiting thread that gets
84/// released to continue will consume and automatically reset the event.
85///
86/// # Examples
87///
88/// ```
89/// use std::thread;
90/// use std::time::Duration;
91/// use win_events::{Event, AutoResetEvent};
92///
93/// let evt_started = AutoResetEvent::new(false);
94/// let evt_started2 = evt_started.clone();
95///
96/// // spawn a thread and set the cloned event
97/// thread::spawn(move|| {
98///     evt_started2.set();
99/// });
100///
101/// // Wait for the started event
102/// evt_started.wait(Duration::from_millis(100)).unwrap();
103/// assert!(!evt_started.is_set())
104/// ```
105#[derive(Clone)]
106pub struct AutoResetEvent {
107    info: Arc<EventHandle>,
108}
109
110impl AutoResetEvent {
111    /// Creates a new AutoResetEvent and initialized the value.
112    ///
113    /// # Examples
114    ///
115    /// ```
116    /// use win_events::AutoResetEvent;
117    ///
118    /// let evt = AutoResetEvent::new(false);
119    /// ```
120    pub fn new(init: bool) -> AutoResetEvent {
121        let state: Box<dyn EventState> = Box::new(AutoResetEventInfo::new(init));
122        AutoResetEvent {
123            info: Arc::new(EventHandle::new(state)),
124        }
125    }
126
127    /// Gets the current state of the event.
128    ///
129    /// # Examples
130    ///
131    /// ```
132    /// use win_events::AutoResetEvent;
133    ///
134    /// let evt = AutoResetEvent::new(true);
135    /// assert!(evt.is_set())
136    ///  ```
137    pub fn is_set(&self) -> bool {
138        self.info.is_set()
139    }
140
141    /// Sets the event and fires a signal to any threads waiting on the event.
142    ///
143    /// # Examples
144    ///
145    /// ```
146    /// use win_events::AutoResetEvent;
147    ///
148    /// let evt = AutoResetEvent::new(false);
149    /// evt.set();
150    /// assert!(evt.is_set())
151    /// ```
152    pub fn set(&self) {
153        self.info.set()
154    }
155
156    /// Sets the even, causing any waiting threads to receive a signal.
157    ///
158    /// # Examples
159    ///
160    /// ```
161    /// use win_events::AutoResetEvent;
162    ///
163    /// let evt = AutoResetEvent::new(false);
164    /// evt.clear();
165    /// assert!(!evt.is_set())
166    /// ```
167    pub fn clear(&self) {
168        self.info.clear()
169    }
170    /// Creates a new AutoResetEvent and initialized the value.
171    ///
172    /// # Examples
173    ///
174    /// ```
175    /// use std::thread::{sleep, spawn};
176    /// use std::time::Duration;
177    /// use win_events::AutoResetEvent;
178    ///
179    /// let evt = AutoResetEvent::new(false);
180    /// let evt_inner = evt.clone();
181    ///
182    /// let worker = spawn(move || {
183    ///    sleep(Duration::from_millis(3));
184    ///    evt_inner.set()
185    /// });
186    ///
187    /// let wait_result = evt.wait(Duration::from_millis(100)).unwrap();
188    /// assert!(wait_result && !evt.is_set())
189    /// ```
190    pub fn wait(&self, dur: Duration) -> Result<bool, Box<dyn Error>> {
191        wait_one(self, dur)
192    }
193}
194
195impl Event for AutoResetEvent {
196    fn handle(&self) -> &Arc<EventHandle> {
197        &self.info
198    }
199}