irox_tools/sync/
exchange.rs1extern crate alloc;
6
7use alloc::sync::Arc;
8use core::sync::atomic::{AtomicBool, Ordering};
9use std::sync::Mutex;
10
11pub struct Exchanger<T> {
14 new_data: Arc<AtomicBool>,
15 data: Arc<Mutex<Option<T>>>,
16}
17impl<T> Default for Exchanger<T> {
18 fn default() -> Exchanger<T> {
19 Self {
20 new_data: Arc::new(AtomicBool::new(false)),
21 data: Arc::new(Mutex::new(None)),
22 }
23 }
24}
25impl<T> Clone for Exchanger<T> {
26 fn clone(&self) -> Exchanger<T> {
27 Self {
28 new_data: self.new_data.clone(),
29 data: self.data.clone(),
30 }
31 }
32}
33impl<T> Exchanger<T> {
34 pub fn new_data_available(&self) -> bool {
36 self.new_data.load(Ordering::Relaxed)
37 }
38 pub fn set_data_changed(&self) {
40 self.new_data.store(true, Ordering::Relaxed);
41 }
42
43 pub fn replace_data(&self, new_data: T) -> Option<T> {
45 let mut old = None;
46 if let Ok(mut lock) = self.data.lock() {
47 old = lock.replace(new_data);
48 }
49 self.new_data.store(true, Ordering::Relaxed);
50 old
51 }
52 pub fn take_data(&self) -> Option<T> {
54 if !self.new_data_available() {
55 return None;
56 }
57 self.new_data.store(false, Ordering::Relaxed);
58 if let Ok(mut lock) = self.data.lock() {
59 return lock.take();
60 }
61 None
62 }
63}