Skip to content

Commit 22d3321

Browse files
appaquetdwrensha
authored andcommitted
Atomic read limiter
1 parent 486d0d7 commit 22d3321

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

capnp/src/private/arena.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
// THE SOFTWARE.
2020

2121
use alloc::vec::Vec;
22-
use core::cell::{Cell, RefCell};
22+
use core::cell::RefCell;
23+
use core::sync::atomic::{AtomicU64, Ordering};
2324
use core::slice;
2425
use core::u64;
2526

@@ -31,21 +32,25 @@ use crate::{Error, OutputSegments, Result};
3132
pub type SegmentId = u32;
3233

3334
pub struct ReadLimiter {
34-
pub limit: Cell<u64>,
35+
pub limit: u64,
36+
pub read: AtomicU64,
3537
}
3638

3739
impl ReadLimiter {
3840
pub fn new(limit: u64) -> ReadLimiter {
39-
ReadLimiter { limit: Cell::new(limit) }
41+
ReadLimiter {
42+
limit,
43+
read: AtomicU64::new(0),
44+
}
4045
}
4146

4247
#[inline]
4348
pub fn can_read(&self, amount: u64) -> Result<()> {
44-
let current = self.limit.get();
45-
if amount > current {
49+
let read = self.read.fetch_add(amount, Ordering::Relaxed) + amount;
50+
51+
if read > self.limit {
4652
Err(Error::failed(format!("read limit exceeded")))
4753
} else {
48-
self.limit.set(current - amount);
4954
Ok(())
5055
}
5156
}

0 commit comments

Comments
 (0)