use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use tokio::sync::Notify;
#[derive(Debug, Clone)]
pub(crate) struct CountDownLatch {
count: Arc<AtomicUsize>,
notify: Arc<Notify>,
}
impl CountDownLatch {
pub fn new(count: usize) -> Self {
let notify = Arc::new(Notify::new());
if count == 0 {
notify.notify_one();
}
Self {
count: Arc::new(AtomicUsize::new(count)),
notify,
}
}
pub async fn count_down(&self) {
if self.count.fetch_sub(1, Ordering::AcqRel) == 1 {
self.notify.notify_waiters();
}
}
pub async fn await_(&self) {
if self.count.load(Ordering::Acquire) == 0 {
return;
}
loop {
self.notify.notified().await;
if self.count.load(Ordering::Acquire) == 0 {
return;
}
}
}
#[allow(dead_code)]
pub fn get_count(&self) -> usize {
self.count.load(Ordering::Relaxed)
}
}