use std::{
cell::Cell,
mem::MaybeUninit,
sync::{Mutex, MutexGuard},
};
use once_cell::sync::Lazy;
static GLOBAL_MUTEX: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
static mut GLOBAL_GUARD: MaybeUninit<MutexGuard<'static, ()>> = MaybeUninit::uninit();
std::thread_local!(static IS_LOCKED: Cell<bool> = Cell::new(false));
struct StdCriticalSection;
critical_section::set_impl!(StdCriticalSection);
unsafe impl critical_section::Impl for StdCriticalSection {
unsafe fn acquire() -> bool {
IS_LOCKED.with(|l| {
if l.get() {
return true;
}
l.set(true);
let guard = match GLOBAL_MUTEX.lock() {
Ok(guard) => guard,
Err(err) => {
err.into_inner()
}
};
unsafe {
GLOBAL_GUARD.write(guard);
}
false
})
}
unsafe fn release(nested_cs: bool) {
if !nested_cs {
unsafe {
GLOBAL_GUARD.as_mut_ptr().drop_in_place();
}
IS_LOCKED.with(|l| l.set(false));
}
}
}