use core::time::Duration;
use safe_lock::SafeLock;
use std::sync::atomic::{AtomicBool, Ordering};
static _STATIC_SAFE_LOCK: SafeLock = SafeLock::new();
#[test]
fn default() {
let lock = SafeLock::default();
let _guard = lock.lock();
}
#[test]
fn sequential() {
let lock = SafeLock::new();
{
let _guard = lock.lock();
}
{
let _guard = lock.lock();
}
}
#[test]
fn quick_unblock() {
static LOCK: SafeLock = SafeLock::new();
let before = std::time::Instant::now();
std::thread::spawn(|| {
let _guard = LOCK.lock();
std::thread::sleep(Duration::from_millis(100));
});
std::thread::sleep(Duration::from_millis(50));
let _guard = LOCK.lock();
let elapsed = std::time::Instant::now().saturating_duration_since(before);
assert!((100..150).contains(&elapsed.as_millis()), "{elapsed:?}");
}
#[test]
fn multiple_threads() {
static LOCK: SafeLock = SafeLock::new();
static FLAG: AtomicBool = AtomicBool::new(false);
let mut join_handles = Vec::new();
for _ in 0..10 {
join_handles.push(std::thread::spawn(|| {
for _ in 0..100 {
let _guard = LOCK.lock();
assert!(!FLAG.swap(true, Ordering::SeqCst));
std::thread::sleep(Duration::from_millis(1));
assert!(FLAG.swap(false, Ordering::SeqCst));
}
}));
}
for join_handle in join_handles.drain(..) {
join_handle.join().unwrap();
}
}