use std::cell::Cell;
thread_local! {
static SYNC_APPLYING: Cell<bool> = const { Cell::new(false) };
}
pub struct SyncApplyGuard {
_private: (),
}
impl SyncApplyGuard {
#[inline]
pub fn enter() -> Self {
SYNC_APPLYING.set(true);
SyncApplyGuard { _private: () }
}
}
impl Drop for SyncApplyGuard {
#[inline]
fn drop(&mut self) {
SYNC_APPLYING.set(false);
}
}
#[inline]
pub fn is_sync_applying() -> bool {
SYNC_APPLYING.get()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_is_false() {
assert!(!is_sync_applying());
}
#[test]
fn test_guard_sets_and_resets() {
assert!(!is_sync_applying());
{
let _guard = SyncApplyGuard::enter();
assert!(is_sync_applying());
}
assert!(!is_sync_applying());
}
#[test]
fn test_nested_guards() {
assert!(!is_sync_applying());
{
let _outer = SyncApplyGuard::enter();
assert!(is_sync_applying());
{
let _inner = SyncApplyGuard::enter();
assert!(is_sync_applying());
}
assert!(!is_sync_applying());
}
assert!(!is_sync_applying());
}
#[test]
fn test_guard_resets_on_panic() {
assert!(!is_sync_applying());
let result = std::panic::catch_unwind(|| {
let _guard = SyncApplyGuard::enter();
assert!(is_sync_applying());
panic!("intentional panic");
});
assert!(result.is_err());
assert!(!is_sync_applying());
}
}