Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_core/src/macros/sync.rs

5.7 KiB, 10 runs

created by r1870400018:104, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1#[macro_export]
2/// Captures and propagates a `RwLock` poisoning error when reading.
3///
4///```
5/// use oxedyne_fe2o3_core::prelude::*;
6/// use std::sync::{std::sync::Arc, RwLock};
7///
8/// fn main() -> Outcome<()> {
9/// let n = std::sync::Arc::new(RwLock::new(42));
10/// let n_ul = lock_read!(n);
11/// assert_eq!(*n_ul, 42);
12/// Ok(())
13/// }
14///
15///```
16macro_rules! lock_read {
17 ($locked:expr, $($arg:tt)*) => {
18 match $locked.read() {
19 Err(_) => {
20 return Err(Error::Local(ErrMsg {
21 tags: &[ErrTag::Lock, ErrTag::Poisoned, ErrTag::Read],
22 msg: errmsg!($($arg)*),
23 }));
24 },
25 Ok(v) => v,
26 }
27 };
28 ($locked:expr) => {
29 match $locked.read() {
30 Err(_) => {
31 return Err(Error::Local(ErrMsg {
32 tags: &[ErrTag::Lock, ErrTag::Poisoned, ErrTag::Read],
33 msg: errmsg!("While locking {:?} for reading", $locked),
34 }));
35 },
36 Ok(v) => v,
37 }
38 }
39}
40
41#[macro_export]
42/// Captures and propagates a `RwLock` poisoning error when writing.
43///
44///```
45/// use oxedyne_fe2o3_core::prelude::*;
46/// use std::sync::{std::sync::Arc, RwLock};
47///
48/// fn main() -> Outcome<()> {
49/// let n = std::sync::Arc::new(RwLock::new(41));
50/// let mut n_ul = lock_write!(n);
51/// *n_ul += 1;
52/// assert_eq!(*n_ul, 42);
53/// Ok(())
54/// }
55///
56///```
57macro_rules! lock_write {
58 ($locked:expr, $($arg:tt)*) => {
59 match $locked.write() {
60 Err(_) => {
61 return Err(Error::Local(ErrMsg {
62 tags: &[ErrTag::Lock, ErrTag::Poisoned, ErrTag::Write],
63 msg: errmsg!($($arg)*),
64 }));
65 },
66 Ok(v) => v,
67 }
68 };
69 ($locked:expr) => {
70 match $locked.write() {
71 Err(_) => {
72 return Err(Error::Local(ErrMsg {
73 tags: &[ErrTag::Lock, ErrTag::Poisoned, ErrTag::Write],
74 msg: errmsg!("While locking {:?} for writing", $locked),
75 }));
76 },
77 Ok(v) => v,
78 }
79 }
80}
81
82#[macro_export]
83/// Captures and propagates a `Mutex` poisoning error when locking.
84///
85///```
86/// use oxedyne_fe2o3_core::prelude::*;
87/// use std::sync::{Arc, Mutex};
88///
89/// fn main() -> Outcome<()> {
90/// let n = Arc::new(Mutex::new(42));
91/// let guard = lock_mutex!(n);
92/// assert_eq!(*guard, 42);
93/// Ok(())
94/// }
95///
96///```
97macro_rules! lock_mutex {
98 ($locked:expr, $($arg:tt)*) => {
99 match $locked.lock() {
100 Err(_) => {
101 return Err(Error::Local(ErrMsg {
102 tags: &[ErrTag::Lock, ErrTag::Poisoned],
103 msg: errmsg!($($arg)*),
104 }));
105 },
106 Ok(v) => v,
107 }
108 };
109 ($locked:expr) => {
110 match $locked.lock() {
111 Err(_) => {
112 return Err(Error::Local(ErrMsg {
113 tags: &[ErrTag::Lock, ErrTag::Poisoned],
114 msg: errmsg!("Mutex lock failed: poisoned lock"),
115 }));
116 },
117 Ok(v) => v,
118 }
119 }
120}
121
122#[macro_export]
123/// Handles `Mutex` locks in thread contexts where we can't return `Outcome`.
124/// Prints an error message and returns early on poisoned mutex.
125///
126///```ignore
127/// // Use in thread contexts
128/// use oxedyne_fe2o3_core::prelude::*;
129/// use std::sync::{Arc, Mutex};
130/// use std::thread;
131///
132/// let data = Arc::new(Mutex::new(42));
133/// let data_clone = Arc::clone(&data);
134///
135/// thread::spawn(move || {
136/// let guard = lock_mutex_thread!(data_clone, "updating data");
137/// // Use guard...
138/// });
139///```
140macro_rules! lock_mutex_thread {
141 ($locked:expr, $context:expr) => {
142 match $locked.lock() {
143 Ok(guard) => guard,
144 Err(_) => {
145 eprintln!("Thread: poisoned mutex in {}", $context);
146 return;
147 }
148 }
149 };
150}
151
152#[macro_export]
153macro_rules! lock_read_or_recover {
154 ($locked:expr, $($arg:tt)*) => {
155 match $locked.read() {
156 Ok(guard) => guard,
157 Err(poisoned) => {
158 warn!($($arg)*);
159 poisoned.into_inner()
160 },
161 }
162 };
163 ($locked:expr) => {
164 match $locked.read() {
165 Ok(guard) => guard,
166 Err(poisoned) => {
167 warn!("RwLock poisoned while reading; recovering with possibly inconsistent data.");
168 poisoned.into_inner()
169 },
170 }
171 };
172}
173
174#[macro_export]
175macro_rules! lock_write_or_recover {
176 ($locked:expr, $($arg:tt)*) => {
177 match $locked.write() {
178 Ok(guard) => guard,
179 Err(poisoned) => {
180 warn!($($arg)*);
181 poisoned.into_inner()
182 },
183 }
184 };
185 ($locked:expr) => {
186 match $locked.write() {
187 Ok(guard) => guard,
188 Err(poisoned) => {
189 warn!("RwLock poisoned while writing; recovering with possibly inconsistent data.");
190 poisoned.into_inner()
191 },
192 }
193 };
194}
195
196#[macro_export]
197macro_rules! lock_mutex_or_recover {
198 ($locked:expr, $($arg:tt)*) => {
199 match $locked.lock() {
200 Ok(guard) => guard,
201 Err(poisoned) => {
202 warn!($($arg)*);
203 poisoned.into_inner()
204 },
205 }
206 };
207 ($locked:expr) => {
208 match $locked.lock() {
209 Ok(guard) => guard,
210 Err(poisoned) => {
211 warn!("Mutex poisoned; recovering with possibly inconsistent data.");
212 poisoned.into_inner()
213 },
214 }
215 };
216}
217