@@ -25,11 +25,10 @@ pub use sync::ReadLimiter;
25
25
#[ cfg( feature = "sync_reader" ) ]
26
26
mod sync {
27
27
use crate :: { Error , Result } ;
28
- use core:: sync:: atomic:: { AtomicUsize , AtomicBool , Ordering } ;
28
+ use core:: sync:: atomic:: { AtomicUsize , Ordering } ;
29
29
30
30
pub struct ReadLimiter {
31
31
pub limit : AtomicUsize ,
32
- pub limit_reached : AtomicBool ,
33
32
}
34
33
35
34
impl ReadLimiter {
@@ -40,22 +39,21 @@ mod sync {
40
39
41
40
ReadLimiter {
42
41
limit : AtomicUsize :: new ( limit as usize ) ,
43
- limit_reached : AtomicBool :: new ( false ) ,
44
42
}
45
43
}
46
44
47
45
#[ inline]
48
46
pub fn can_read ( & self , amount : usize ) -> Result < ( ) > {
49
- let limit_reached = self . limit_reached . load ( Ordering :: Relaxed ) ;
50
- if limit_reached {
47
+ let cur_limit = self . limit . load ( Ordering :: Relaxed ) ;
48
+ if cur_limit < amount {
51
49
return Err ( Error :: failed ( format ! ( "read limit exceeded" ) ) ) ;
52
50
}
53
51
54
52
let prev_limit = self . limit . fetch_sub ( amount, Ordering :: Relaxed ) ;
55
- if prev_limit == amount {
56
- self . limit_reached . store ( true , Ordering :: Relaxed ) ;
57
- } else if prev_limit < amount {
58
- self . limit_reached . store ( true , Ordering :: Relaxed ) ;
53
+ if prev_limit < amount {
54
+ // if the previous limit was lower than the amount we read, the limit has underflowed
55
+ // and wrapped around so we need to reset it to 0 for next reader to fail
56
+ self . limit . store ( 0 , Ordering :: Relaxed ) ;
59
57
return Err ( Error :: failed ( format ! ( "read limit exceeded" ) ) ) ;
60
58
}
61
59
0 commit comments