mod futures;
mod mixed;
pub use futures::{
CapacityGate as FuturesCapacityGate, OwnedPermitGuard as FuturesOwnedPermitGuard,
};
pub use mixed::{AcquireFuture, CapacityGate};
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
use std::thread;
use std::time::Duration;
#[test]
fn test_capacity_gate_sync_regression() {
let gate = Arc::new(CapacityGate::new(1));
assert!(gate.try_acquire());
gate.close();
let gate_clone = gate.clone();
let handle = thread::spawn(move || {
gate_clone.acquire_sync();
});
thread::sleep(Duration::from_millis(100));
let is_blocked = !handle.is_finished();
if is_blocked {
gate.release();
}
handle.join().expect("Sender thread panicked on join");
assert!(
!is_blocked,
"REGRESSION: acquire_sync() deadlocked permanently on a closed CapacityGate!"
);
}
#[cfg(not(miri))]
#[tokio::test]
async fn test_capacity_gate_async_regression() {
let gate = Arc::new(CapacityGate::new(1));
assert!(gate.try_acquire());
gate.close();
let acquire_fut = gate.acquire_async();
let result = tokio::time::timeout(Duration::from_millis(100), acquire_fut).await;
assert!(
result.is_ok(),
"REGRESSION: acquire_async() deadlocked and timed out on a closed CapacityGate!"
);
}
}