Do not wait in PersistenceNotifier when the persist flag is set
authorMatt Corallo <git@bluematt.me>
Fri, 7 May 2021 22:17:29 +0000 (22:17 +0000)
committerMatt Corallo <git@bluematt.me>
Fri, 14 May 2021 23:20:27 +0000 (23:20 +0000)
When we had a event which caused us to set the persist flag in a
PersistenceNotifier in between wait calls, we will still wait,
potentially not persisting a ChannelManager when we should.

Worse, for wait_timeout, this caused us to always wait up to the
timeout, but then always return true that a persistence is needed.

Instead, we simply check the persist flag before waiting, returning
immediately if it is set.

lightning/src/ln/channelmanager.rs

index 9efb6b83b8a2ad3355a392b6203f00f5cd077607..cf6e8cf3f34801f0986f6d63c378bfc9d30a5b95 100644 (file)
@@ -4088,6 +4088,10 @@ impl PersistenceNotifier {
                loop {
                        let &(ref mtx, ref cvar) = &self.persistence_lock;
                        let mut guard = mtx.lock().unwrap();
+                       if *guard {
+                               *guard = false;
+                               return;
+                       }
                        guard = cvar.wait(guard).unwrap();
                        let result = *guard;
                        if result {
@@ -4103,6 +4107,10 @@ impl PersistenceNotifier {
                loop {
                        let &(ref mtx, ref cvar) = &self.persistence_lock;
                        let mut guard = mtx.lock().unwrap();
+                       if *guard {
+                               *guard = false;
+                               return true;
+                       }
                        guard = cvar.wait_timeout(guard, max_wait).unwrap().0;
                        // Due to spurious wakeups that can happen on `wait_timeout`, here we need to check if the
                        // desired wait time has actually passed, and if not then restart the loop with a reduced wait