use crate::errors::Result;
use crate::fitsfile::FitsFile;
use std::sync::{Arc, Mutex, MutexGuard};
#[derive(Clone)]
pub struct ThreadsafeFitsFile(Arc<Mutex<FitsFile>>);
unsafe impl Send for ThreadsafeFitsFile {}
impl FitsFile {
pub fn threadsafe(self) -> ThreadsafeFitsFile {
#[allow(clippy::arc_with_non_send_sync)]
ThreadsafeFitsFile(Arc::new(Mutex::new(self)))
}
}
impl ThreadsafeFitsFile {
pub fn lock(&self) -> Result<MutexGuard<'_, FitsFile>> {
self.0.lock().map_err(From::from)
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::thread;
#[cfg(target_arch = "arm")]
fn num_threads() -> usize {
100
}
#[cfg(not(target_arch = "arm"))]
fn num_threads() -> usize {
10_000
}
#[test]
fn test_using_other_threads() {
let f = FitsFile::open("../testdata/full_example.fits").unwrap();
let f = f.threadsafe();
let mut handles = Vec::new();
for i in 0..num_threads() {
let f1 = f.clone();
let handle = thread::spawn(move || {
let mut t = f1.lock().unwrap();
let hdu_num = i % 2;
let _hdu = t.hdu(hdu_num).unwrap();
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
}
}