use std::{io, thread::JoinHandle, time::Instant};
pub struct AutoJoin<T> {
jh: Option<JoinHandle<T>>
}
impl<T> AutoJoin<T> {
pub fn join(mut self) -> std::thread::Result<T> {
if let Some(jh) = self.jh.take() {
jh.join()
} else {
Err(Box::new(io::Error::new(
io::ErrorKind::NotFound,
"already consumed"
)))
}
}
}
impl<T> Drop for AutoJoin<T> {
fn drop(&mut self) {
if let Some(jh) = self.jh.take() {
let _ = jh.join();
}
}
}
pub fn spawn_autojoin<F, T>(f: F) -> AutoJoin<T>
where
F: FnOnce() -> T,
F: Send + 'static,
T: Send + 'static
{
AutoJoin {
jh: Some(std::thread::spawn(f))
}
}
pub fn expect_runtime<F>(edur: std::time::Duration, f: F)
where
F: FnOnce()
{
let start = Instant::now();
f();
let dur = Instant::now() - start;
assert!(dur > edur);
}