Add `CondVar::wait_{timeout_,}while` to `debug_sync`
authorMatt Corallo <git@bluematt.me>
Mon, 20 Mar 2023 18:26:39 +0000 (18:26 +0000)
committerMatt Corallo <git@bluematt.me>
Mon, 3 Apr 2023 16:49:54 +0000 (16:49 +0000)
These are useful, but we previously couldn't use them due to our
MSRV. Now that we can, we should use them, so we expose them via
our normal debug_sync wrappers.

lightning/src/sync/debug_sync.rs
lightning/src/sync/nostd_sync.rs

index 11557be82afec418be0abce3b38117ce04582fd0..edf7c753537e105d842f3143eadb55840cb8da2a 100644 (file)
@@ -12,6 +12,8 @@ use std::sync::RwLockReadGuard as StdRwLockReadGuard;
 use std::sync::RwLockWriteGuard as StdRwLockWriteGuard;
 use std::sync::Condvar as StdCondvar;
 
+pub use std::sync::WaitTimeoutResult;
+
 use crate::prelude::HashMap;
 
 use super::{LockTestExt, LockHeldState};
@@ -40,12 +42,27 @@ impl Condvar {
                self.inner.wait(guard.into_inner()).map(|lock| MutexGuard { mutex, lock }).map_err(|_| ())
        }
 
+       pub fn wait_while<'a, T, F: FnMut(&mut T) -> bool>(&'a self, guard: MutexGuard<'a, T>, condition: F)
+       -> LockResult<MutexGuard<'a, T>> {
+               let mutex: &'a Mutex<T> = guard.mutex;
+               self.inner.wait_while(guard.into_inner(), condition).map(|lock| MutexGuard { mutex, lock })
+                       .map_err(|_| ())
+       }
+
        #[allow(unused)]
        pub fn wait_timeout<'a, T>(&'a self, guard: MutexGuard<'a, T>, dur: Duration) -> LockResult<(MutexGuard<'a, T>, ())> {
                let mutex = guard.mutex;
                self.inner.wait_timeout(guard.into_inner(), dur).map(|(lock, _)| (MutexGuard { mutex, lock }, ())).map_err(|_| ())
        }
 
+       #[allow(unused)]
+       pub fn wait_timeout_while<'a, T, F: FnMut(&mut T) -> bool>(&'a self, guard: MutexGuard<'a, T>, dur: Duration, condition: F)
+       -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)> {
+               let mutex = guard.mutex;
+               self.inner.wait_timeout_while(guard.into_inner(), dur, condition).map_err(|_| ())
+                       .map(|(lock, e)| (MutexGuard { mutex, lock }, e))
+       }
+
        pub fn notify_all(&self) { self.inner.notify_all(); }
 }
 
index 17307997d8176cc2b82a0d9559307971f3e2c252..ee3e375028eba44bbb0ac723b0eb520c398be227 100644 (file)
@@ -8,6 +8,11 @@ pub type LockResult<Guard> = Result<Guard, ()>;
 
 pub struct Condvar {}
 
+pub struct WaitTimeoutResult(bool);
+impl WaitTimeoutResult {
+       pub fn timed_out(&self) -> bool { self.0 }
+}
+
 impl Condvar {
        pub fn new() -> Condvar {
                Condvar { }
@@ -22,6 +27,22 @@ impl Condvar {
                Ok((guard, ()))
        }
 
+       pub fn wait_while<'a, T, F: FnMut(&mut T) -> bool>(&'a self, mut guard: MutexGuard<'a, T>, mut condition: F)
+       -> LockResult<MutexGuard<'a, T>> {
+               assert!(!condition(&mut *guard));
+               Ok(guard)
+       }
+
+       #[allow(unused)]
+       pub fn wait_timeout_while<'a, T, F: FnMut(&mut T) -> bool>(&'a self, mut guard: MutexGuard<'a, T>, dur: Duration, mut condition: F)
+       -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)> {
+               if condition(&mut *guard) {
+                       Ok((guard, WaitTimeoutResult(true)))
+               } else {
+                       Ok((guard, WaitTimeoutResult(false)))
+               }
+       }
+
        pub fn notify_all(&self) {}
 }