diff --git a/src/sync/condvar.rs b/src/sync/condvar.rs
index b173e4e..205d518 100644
--- a/src/sync/condvar.rs
+++ b/src/sync/condvar.rs
@@ -39,6 +39,23 @@ impl Condvar {
         Ok(guard)
     }
 
+    /// Blocks the current thread until this condition variable receives a notification and the
+    /// provided condition is false.
+    pub fn wait_while<'a, T, F>(
+        &self,
+        mut guard: MutexGuard<'a, T>,
+        mut condition: F,
+    ) -> LockResult<MutexGuard<'a, T>>
+    where
+        F: FnMut(&mut T) -> bool,
+    {
+        while condition(&mut *guard) {
+            guard = self.wait(guard)?;
+        }
+
+        Ok(guard)
+    }
+
     /// Waits on this condition variable for a notification, timing out after a
     /// specified duration.
     pub fn wait_timeout<'a, T>(
diff --git a/tests/condvar.rs b/tests/condvar.rs
index 6f3a482..03d1ad9 100644
--- a/tests/condvar.rs
+++ b/tests/condvar.rs
@@ -80,3 +80,25 @@ impl Inc {
         self.condvar.notify_all();
     }
 }
+
+#[test]
+fn wait_while() {
+    loom::model(|| {
+        let pair = Arc::new((Mutex::new(true), Condvar::new()));
+        let pair_2 = Arc::clone(&pair);
+
+        thread::spawn(move || {
+            let (lock, cvar) = &*pair_2;
+            let mut pending = lock.lock().unwrap();
+            *pending = false;
+            cvar.notify_one();
+        });
+
+        let (lock, cvar) = &*pair;
+        let guard = cvar
+            .wait_while(lock.lock().unwrap(), |pending| *pending)
+            .unwrap();
+
+        assert_eq!(*guard, false);
+    });
+}