use super::*;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Policy {
Deny,
Block,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Limits {
pub max_concurrent_creations: Option<usize>,
pub policy: Policy,
pub timeout: Option<Duration>,
}
impl Limits {
pub const fn unlimited() -> Self {
Self {
max_concurrent_creations: None,
policy: Policy::Deny,
timeout: None,
}
}
pub const fn deny(max_concurrent_creations: usize) -> Self {
Self {
max_concurrent_creations: Some(max_concurrent_creations),
policy: Policy::Deny,
timeout: None,
}
}
pub const fn block(max_concurrent_creations: usize) -> Self {
Self {
max_concurrent_creations: Some(max_concurrent_creations),
policy: Policy::Block,
timeout: None,
}
}
pub fn with_timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
pub fn block_with_timeout(max_concurrent_creations: usize, timeout: Duration) -> Self {
Self::block(max_concurrent_creations).with_timeout(timeout)
}
}
impl Default for Limits {
fn default() -> Self {
Self::unlimited()
}
}
#[cfg(not(feature = "thread-safe"))]
#[derive(Debug)]
pub(crate) struct Limiter {
pub(super) max: usize,
pub(super) policy: Policy,
pub(super) current: std::cell::Cell<usize>,
pub(super) timeout: Option<Duration>,
}
#[cfg(feature = "thread-safe")]
#[derive(Debug)]
pub(crate) struct Limiter {
pub(super) max: usize,
pub(super) policy: Policy,
pub(super) current: std::sync::Mutex<usize>,
pub(super) condvar: std::sync::Condvar,
pub(super) timeout: Option<Duration>,
#[cfg(feature = "resource-limit-async")]
pub(super) async_semaphore: Shared<Semaphore>,
}
#[derive(Debug)]
pub(crate) enum CreationPermit {
Sync {
limiter: Shared<Limiter>,
},
#[cfg(all(feature = "thread-safe", feature = "resource-limit-async"))]
Async(OwnedSemaphorePermit),
}
impl Drop for CreationPermit {
fn drop(&mut self) {
#[cfg(all(feature = "thread-safe", feature = "resource-limit-async"))]
match self {
Self::Sync { limiter } => limiter.release(),
Self::Async(_permit) => {}
}
#[cfg(not(all(feature = "thread-safe", feature = "resource-limit-async")))]
{
let Self::Sync { limiter } = self;
limiter.release();
}
}
}