pub(crate) mod util;
use std::{panic::catch_unwind, sync::Mutex};
pub use libftd3xx_ffi::*;
use crate::Result;
static mut GLOBAL_LOCK: Mutex<()> = Mutex::new(());
#[allow(clippy::missing_panics_doc)]
pub fn with_global_lock<F, R>(f: F) -> R
where
F: FnOnce() -> R + std::panic::UnwindSafe,
{
unsafe {
let lock = GLOBAL_LOCK.lock().unwrap();
match catch_unwind(f) {
Ok(result) => result,
Err(e) => {
drop(lock);
panic!("panicked while holding global lock: {e:?}");
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_global_lock() {
let _guard = unsafe { GLOBAL_LOCK.lock().unwrap() };
assert!(unsafe { GLOBAL_LOCK.try_lock() }.is_err());
}
#[test]
fn test_global_lock_unpoisoning() {
let result = std::panic::catch_unwind(|| {
with_global_lock(|| {
panic!("test panic");
});
});
assert!(result.is_err());
assert!(unsafe { GLOBAL_LOCK.try_lock().is_ok() });
}
}