use std::fmt::Debug;
use std::sync::Arc;
use std::thread;
use std::time;
use init_once::InitOnce;
struct AnnounceDrop<T: Debug> {
value: T,
}
fn main() {
let init_once = Arc::new(InitOnce::new());
let threads: Vec<_> = (0..10)
.map(|i| {
let init_once = Arc::clone(&init_once);
thread::spawn(move || {
let worker_sleep_dur = time::Duration::from_secs(i);
println!("I am thread {i}, sleeping for {worker_sleep_dur:?}");
thread::sleep(worker_sleep_dur);
let maybe_value = init_once.try_init(|| {
thread::sleep(time::Duration::from_secs(5));
println!("Took a second but we out here");
AnnounceDrop {
value: format!("I am thread {i}, blazing 420"),
}
});
if let Some(AnnounceDrop { value }) = maybe_value {
println!("Read {value:?} from {i}");
} else {
println!("Thread {i} couldn't read value");
}
})
})
.collect();
for handle in threads {
handle.join().unwrap();
}
}
impl<T: Debug> Drop for AnnounceDrop<T> {
fn drop(&mut self) {
println!("Dropping value: {:?}", self.value);
}
}