I don't think this works:
use std::sync::atomic::{AtomicBool, Ordering};
static INITIALISED: AtomicBool = AtomicBool::new(false);
async fn reset_and_seed_db() {
if INITIALISED.swap(true, Ordering::SeqCst) {
return;
}
std::thread::sleep(std::time::Duration::from_millis(100));
println!("Doing stuff. (This must happen first!)")
}
async fn foo() {
reset_and_seed_db().await;
println!("I hope stuff has been done.");
}
#[tokio::main]
async fn main() {
let t1 = tokio::spawn(foo());
let t2 = tokio::spawn(foo());
let (r1, r2) = tokio::join!(t1, t2);
r1.unwrap();
r2.unwrap();
}
Output:
I hope stuff has been done.
Doing stuff. (This must happen first!)
I hope stuff has been done.
P.S.: What you really need is an async
(!) mutex like @Heliozoa suggested, because you want to suspend the other tasks until initialization is complete. (see Playground with tokio
's Mutex
)