use std::cell::Cell;
use std::rc::Rc;
use crate::errors::*;
pub struct ReentrantLimit(Rc<Cell<usize>>);
impl ReentrantLimit {
pub fn new(limit: usize) -> Self {
ReentrantLimit(Rc::new(Cell::new(limit)))
}
pub fn acquire<S: Into<String>>(&mut self, kind: S) -> Result<ReentrantGuard> {
if self.0.get() == 0 {
return Err(Error::DeRecursionLimitExceeded { kind: kind.into() });
}
self.0.set(self.0.get() - 1);
Ok(ReentrantGuard(self.0.clone()))
}
}
pub struct ReentrantGuard(Rc<Cell<usize>>);
impl Drop for ReentrantGuard {
fn drop(&mut self) {
self.0.set(self.0.get() + 1);
}
}