Skip to content

Commit

Permalink
Replace AtomicUsize with Cell<usize> in the recursion counter (#1098
Browse files Browse the repository at this point in the history
)
  • Loading branch information
wzzzzd authored Jan 24, 2024
1 parent c86508b commit 1b6b6aa
Showing 1 changed file with 10 additions and 9 deletions.
19 changes: 10 additions & 9 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ macro_rules! return_ok_if_some {
#[cfg(feature = "std")]
/// Implementation [`RecursionCounter`] if std is available
mod recursion {
use core::sync::atomic::{AtomicUsize, Ordering};
use std::cell::Cell;
use std::rc::Rc;

use super::ParserError;
Expand All @@ -70,12 +70,11 @@ mod recursion {
/// each call to `try_decrease()`, when it reaches 0 an error will
/// be returned.
///
/// Note: Uses an Rc and AtomicUsize in order to satisfy the Rust
/// Note: Uses an Rc and Cell in order to satisfy the Rust
/// borrow checker so the automatic DepthGuard decrement a
/// reference to the counter. The actual value is not modified
/// concurrently
/// reference to the counter.
pub(crate) struct RecursionCounter {
remaining_depth: Rc<AtomicUsize>,
remaining_depth: Rc<Cell<usize>>,
}

impl RecursionCounter {
Expand All @@ -94,29 +93,31 @@ mod recursion {
/// Returns a [`DepthGuard`] which will adds 1 to the
/// remaining depth upon drop;
pub fn try_decrease(&self) -> Result<DepthGuard, ParserError> {
let old_value = self.remaining_depth.fetch_sub(1, Ordering::SeqCst);
let old_value = self.remaining_depth.get();
// ran out of space
if old_value == 0 {
Err(ParserError::RecursionLimitExceeded)
} else {
self.remaining_depth.set(old_value - 1);
Ok(DepthGuard::new(Rc::clone(&self.remaining_depth)))
}
}
}

/// Guard that increass the remaining depth by 1 on drop
pub struct DepthGuard {
remaining_depth: Rc<AtomicUsize>,
remaining_depth: Rc<Cell<usize>>,
}

impl DepthGuard {
fn new(remaining_depth: Rc<AtomicUsize>) -> Self {
fn new(remaining_depth: Rc<Cell<usize>>) -> Self {
Self { remaining_depth }
}
}
impl Drop for DepthGuard {
fn drop(&mut self) {
self.remaining_depth.fetch_add(1, Ordering::SeqCst);
let old_value = self.remaining_depth.get();
self.remaining_depth.set(old_value + 1);
}
}
}
Expand Down

0 comments on commit 1b6b6aa

Please sign in to comment.