sync: Add wait_while variants to condvar wrapper

wait_while and wait_timeout_while are similar to wait and wait_timeout,
but they implicitly wrap the wait in a while loop to handle spurious
wakeups.

BUG=b:192243046
TEST=cargo test

Change-Id: I2b4c2b6784df9128872772880e7045a09d1d8c22
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2992161
Reviewed-by: Chih-Yang Hsia <paulhsia@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Benjamin Gordon <bmgordon@chromium.org>
This commit is contained in:
Benjamin Gordon 2021-06-28 20:30:17 -06:00 committed by Commit Bot
parent 114d7d7ccd
commit 01743e49eb

View file

@ -63,6 +63,35 @@ impl Condvar {
.expect(CONDVAR_POISONED)
}
/// Waits on a condvar, blocking the current thread until it is notified and
/// the provided condition is false.
pub fn wait_while<'a, T, F>(&self, guard: MutexGuard<'a, T>, condition: F) -> MutexGuard<'a, T>
where
F: FnMut(&mut T) -> bool,
{
match self.std.wait_while(guard, condition) {
Ok(result) => result,
Err(_) => panic!("condvar is poisoned"),
}
}
/// Waits on a condvar, blocking the current thread until it is notified and
/// the provided condition is false, or until the specified duration has elapsed.
pub fn wait_timeout_while<'a, T, F>(
&self,
guard: MutexGuard<'a, T>,
dur: Duration,
condition: F,
) -> (MutexGuard<'a, T>, WaitTimeoutResult)
where
F: FnMut(&mut T) -> bool,
{
match self.std.wait_timeout_while(guard, dur, condition) {
Ok(result) => result,
Err(_) => panic!("condvar is poisoned"),
}
}
/// Notifies one thread blocked by this condvar.
pub fn notify_one(&self) {
self.std.notify_one();