From 1b6b6aa65f3c4cea52feb831a5774eed3a4e9ba1 Mon Sep 17 00:00:00 2001 From: wzzzzd <108382774+wzzzzd@users.noreply.github.com> Date: Thu, 25 Jan 2024 03:29:51 +0800 Subject: [PATCH] Replace `AtomicUsize` with `Cell` in the recursion counter (#1098) --- src/parser/mod.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 041f0aa9..fbbc4e03 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -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; @@ -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, + remaining_depth: Rc>, } impl RecursionCounter { @@ -94,11 +93,12 @@ mod recursion { /// Returns a [`DepthGuard`] which will adds 1 to the /// remaining depth upon drop; pub fn try_decrease(&self) -> Result { - 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))) } } @@ -106,17 +106,18 @@ mod recursion { /// Guard that increass the remaining depth by 1 on drop pub struct DepthGuard { - remaining_depth: Rc, + remaining_depth: Rc>, } impl DepthGuard { - fn new(remaining_depth: Rc) -> Self { + fn new(remaining_depth: Rc>) -> 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); } } }