I'm writing a function that needs to use mutable static variables to work (a weird implementation of a message loop). In order to allow only one writer to access those variables at any given time, I need to make the access to this function exclusive (to the first thread that accesses it).
My first guess was to use an AtomicBool
:
use std::sync::atomic::{Ordering, AtomicBool};
static FLAG: AtomicBool = AtomicBool::new(false);
fn my_exclusive_function() {
if FLAG.load(Ordering::SeqCst) {
panic!("Haha, too late!")
}
FLAG.store(true, Ordering::SeqCst);
/* Do stuff */
}
This code has an obvious flaw: if two threads happen to read FLAG
at the same time, they would both think that this is ok for them to continue.
Then I thought about using a Mutex<()>
for its lock.
use std::sync::Mutex;
static FLAG: Mutex<()> = Mutex::new(());
fn my_exclusive_function() {
let _lock = FLAG.try_lock() {
Ok(lock) => lock,
Err(_) => panic!("Haha, too late!"),
};
/* Do stuff */
// `_lock` gets dropped here, another thread can now access the function
}
There are two problems here:
Mutex::new
is not a const
function which makes me unable to initialize the Mutex
. I could use a library like lazy_static
here but if I can avoid an additional dependency, it would be great.
- Even if I use
lazy_static
, a user-defined function (the handler inside of the message loop actually) could panic and poison the mutex. Here again, I could use a thread-party library like parking_lot
but that would be yet anther additional dependency.
I'm willing to use those if there is no alternatives but if I can avoid it, that is better.
What would the right way to do this look like? Is it just a matter of Ordering
?
Related question that did not help me
question from:
https://stackoverflow.com/questions/65599268/how-to-ensure-a-piece-of-code-is-always-used-by-one-thread-at-any-given-time 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…