Skip to content

Commit ad728a0

Browse files
committed
Implement wait_while for condvar
1 parent 05885ec commit ad728a0

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

Diff for: src/sync/condvar.rs

+17
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,23 @@ impl Condvar {
3939
Ok(guard)
4040
}
4141

42+
/// Blocks the current thread until this condition variable receives a notification and the
43+
/// provided condition is false.
44+
pub fn wait_while<'a, T, F>(
45+
&self,
46+
mut guard: MutexGuard<'a, T>,
47+
mut condition: F,
48+
) -> LockResult<MutexGuard<'a, T>>
49+
where
50+
F: FnMut(&mut T) -> bool,
51+
{
52+
while condition(&mut *guard) {
53+
guard = self.wait(guard)?;
54+
}
55+
56+
Ok(guard)
57+
}
58+
4259
/// Waits on this condition variable for a notification, timing out after a
4360
/// specified duration.
4461
pub fn wait_timeout<'a, T>(

Diff for: tests/condvar.rs

+22
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,25 @@ impl Inc {
8080
self.condvar.notify_all();
8181
}
8282
}
83+
84+
#[test]
85+
fn wait_while() {
86+
loom::model(|| {
87+
let pair = Arc::new((Mutex::new(true), Condvar::new()));
88+
let pair_2 = Arc::clone(&pair);
89+
90+
thread::spawn(move || {
91+
let (lock, cvar) = &*pair_2;
92+
let mut pending = lock.lock().unwrap();
93+
*pending = false;
94+
cvar.notify_one();
95+
});
96+
97+
let (lock, cvar) = &*pair;
98+
let guard = cvar
99+
.wait_while(lock.lock().unwrap(), |pending| *pending)
100+
.unwrap();
101+
102+
assert_eq!(*guard, false);
103+
});
104+
}

0 commit comments

Comments
 (0)