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}