use std::future::Future;
use std::sync::atomic::{AtomicUsize, Ordering};
use tokio::sync::Notify;
static IN_FLIGHT: AtomicUsize = AtomicUsize::new(0);
static FINISHED: Notify = Notify::const_new();
struct InFlight;
impl InFlight {
fn start() -> Self {
IN_FLIGHT.fetch_add(1, Ordering::SeqCst);
Self
}
}
impl Drop for InFlight {
fn drop(&mut self) {
IN_FLIGHT.fetch_sub(1, Ordering::SeqCst);
FINISHED.notify_waiters();
}
}
pub(crate) fn spawn(task: impl Future<Output = ()> + Send + 'static) {
let in_flight = InFlight::start();
tokio::spawn(async move {
task.await;
drop(in_flight);
});
}
pub async fn flush() {
loop {
let finished = FINISHED.notified();
if IN_FLIGHT.load(Ordering::SeqCst) == 0 {
return;
}
finished.await;
}
}