use std::sync::atomic::{AtomicUsize, Ordering};
use super::{
submission_admission::SubmissionAdmission, submit_enter_outcome::SubmitEnterOutcome,
};
pub(super) struct InflightSubmitCounter {
count: AtomicUsize,
}
impl InflightSubmitCounter {
pub(super) fn new() -> Self {
Self {
count: AtomicUsize::new(0),
}
}
pub(super) fn load(&self) -> usize {
self.count.load(Ordering::Acquire)
}
pub(super) fn try_enter(&self, admission: &SubmissionAdmission) -> SubmitEnterOutcome {
if !admission.is_open() {
return SubmitEnterOutcome::Rejected {
became_zero_after_rollback: false,
};
}
self.count.fetch_add(1, Ordering::AcqRel);
if admission.is_open() {
return SubmitEnterOutcome::Entered;
}
let previous = self.count.fetch_sub(1, Ordering::AcqRel);
debug_assert!(
previous > 0,
"thread pool inflight submit counter underflow"
);
SubmitEnterOutcome::Rejected {
became_zero_after_rollback: previous == 1,
}
}
pub(super) fn leave(&self) -> bool {
let previous = self.count.fetch_sub(1, Ordering::AcqRel);
debug_assert!(
previous > 0,
"thread pool inflight submit counter underflow"
);
previous == 1
}
}