From 9670035cdc1b92b4da76e0c2022252c0205ea1f5 Mon Sep 17 00:00:00 2001 From: Pascal Kuthe Date: Fri, 4 Aug 2023 08:55:54 +0200 Subject: [PATCH] fix incorrect unmatched count calculation This could lead to underflow (and crashed in debug builds) --- src/worker.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/worker.rs b/src/worker.rs index 8625974..ab30f95 100644 --- a/src/worker.rs +++ b/src/worker.rs @@ -36,7 +36,6 @@ pub(crate) struct Woker { notify: Arc<(dyn Fn() + Sync + Send)>, pub(crate) items: Arc>, in_flight: Vec, - unmatched: AtomicU32, } impl Woker { @@ -78,7 +77,6 @@ impl Woker { notify, items: Arc::new(boxcar::Vec::with_capacity(2 * 1024, cols)), in_flight: Vec::with_capacity(64), - unmatched: AtomicU32::new(0), }; (pool, worker) } @@ -152,13 +150,11 @@ impl Woker { if cleared { self.last_snapshot = 0; - *self.unmatched.get_mut() = 0; self.matches.clear(); } // TODO: be smarter around reusing past results for rescoring if self.pattern.cols.iter().all(|pat| pat.is_empty()) { - *self.unmatched.get_mut() = 0; self.matches.clear(); self.matches .extend((0..self.last_snapshot).map(|idx| Match { score: 0, idx })); @@ -179,6 +175,7 @@ impl Woker { self.remove_in_flight_matches(); } + let mut unmatched = AtomicU32::new(0); let matchers = &self.matchers; let pattern = &self.pattern; if pattern_status != pattern::Status::Unchanged && !self.matches.is_empty() { @@ -187,6 +184,7 @@ impl Woker { .take_any_while(|_| !self.canceled.load(atomic::Ordering::Relaxed)) .for_each(|match_| { if match_.idx == u32::MAX { + unmatched.fetch_add(1, atomic::Ordering::Relaxed); return; } // safety: in-flight items are never added to the matches @@ -194,7 +192,7 @@ impl Woker { if let Some(score) = pattern.score(item.matcher_columns, matchers.get()) { match_.score = score; } else { - self.unmatched.fetch_add(1, atomic::Ordering::Release); + unmatched.fetch_add(1, atomic::Ordering::Relaxed); match_.score = 0; match_.idx = u32::MAX; } @@ -241,7 +239,7 @@ impl Woker { self.was_canceled = true; } else { self.matches - .truncate(self.matches.len() - take(self.unmatched.get_mut()) as usize); + .truncate(self.matches.len() - take(unmatched.get_mut()) as usize); if self.should_notify.load(atomic::Ordering::Acquire) { (self.notify)(); }