#![cfg(unix)]
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::time::Duration;
#[test]
fn a_child_forked_while_threads_use_hdf5_takes_hdf5s_lock() {
medh5::h5::fork::install();
let stop = Arc::new(AtomicBool::new(false));
let busy: Vec<_> = (0..2)
.map(|_| {
let stop = stop.clone();
std::thread::spawn(move || {
while !stop.load(Ordering::SeqCst) {
medh5::hdf5::sync::sync(|| std::thread::sleep(Duration::from_micros(50)));
}
})
})
.collect();
let mut hung = 0;
for _ in 0..40 {
std::thread::sleep(Duration::from_millis(1));
let pid = unsafe { libc::fork() };
if pid == 0 {
unsafe { libc::alarm(5) };
medh5::hdf5::sync::sync(|| ());
unsafe { libc::_exit(0) };
}
let mut status = 0;
assert_eq!(unsafe { libc::waitpid(pid, &mut status, 0) }, pid);
hung += usize::from(status != 0);
}
stop.store(true, Ordering::SeqCst);
busy.into_iter().for_each(|t| t.join().unwrap());
assert_eq!(hung, 0, "a child found HDF5's lock held");
}