diff --git a/codex-rs/file-search/src/lib.rs b/codex-rs/file-search/src/lib.rs index 70cb583eb..b92f92680 100644 --- a/codex-rs/file-search/src/lib.rs +++ b/codex-rs/file-search/src/lib.rs @@ -681,13 +681,41 @@ mod tests { } impl RecordingReporter { - fn wait_for_complete(&self, timeout: Duration) -> bool { - let completes = self.complete_times.lock().unwrap(); - if !completes.is_empty() { - return true; + fn wait_until( + &self, + mutex: &Mutex, + cv: &Condvar, + timeout: Duration, + mut predicate: F, + ) -> bool + where + F: FnMut(&T) -> bool, + { + let deadline = Instant::now() + timeout; + let mut state = mutex.lock().unwrap(); + loop { + if predicate(&state) { + return true; + } + let remaining = deadline.saturating_duration_since(Instant::now()); + if remaining.is_zero() { + return false; + } + let (next_state, wait_result) = cv.wait_timeout(state, remaining).unwrap(); + state = next_state; + if wait_result.timed_out() { + return predicate(&state); + } } - let (completes, _) = self.complete_cv.wait_timeout(completes, timeout).unwrap(); - !completes.is_empty() + } + + fn wait_for_complete(&self, timeout: Duration) -> bool { + self.wait_until( + &self.complete_times, + &self.complete_cv, + timeout, + |completes| !completes.is_empty(), + ) } fn clear(&self) { self.updates.lock().unwrap().clear(); @@ -699,12 +727,9 @@ mod tests { } fn wait_for_updates_at_least(&self, min_len: usize, timeout: Duration) -> bool { - let updates = self.updates.lock().unwrap(); - if updates.len() >= min_len { - return true; - } - let (updates, _) = self.update_cv.wait_timeout(updates, timeout).unwrap(); - updates.len() >= min_len + self.wait_until(&self.updates, &self.update_cv, timeout, |updates| { + updates.len() >= min_len + }) } fn snapshot(&self) -> FileSearchSnapshot {