diff --git a/src/bitcoin/poller/mod.rs b/src/bitcoin/poller/mod.rs index 95a205352..563ad2f35 100644 --- a/src/bitcoin/poller/mod.rs +++ b/src/bitcoin/poller/mod.rs @@ -36,11 +36,22 @@ impl Poller { Poller { shutdown, handle } } - pub fn stop(self) { + pub fn trigger_stop(&self) { self.shutdown.store(true, atomic::Ordering::Relaxed); + } + + pub fn stop(self) { + self.trigger_stop(); self.handle.join().expect("The poller loop must not fail"); } + pub fn is_stopped(&self) -> bool { + // Doc says "This might return true for a brief moment after the thread’s main function has + // returned, but before the thread itself has stopped running.". But it's not an issue for + // us, as long as the main poller function has returned we are good. + self.handle.is_finished() + } + #[cfg(test)] pub fn test_stop(&mut self) { self.shutdown.store(true, atomic::Ordering::Relaxed); diff --git a/src/lib.rs b/src/lib.rs index be6e1cf22..b57b78d62 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -458,12 +458,22 @@ impl DaemonHandle { Ok(()) } - // NOTE: this moves out the data as it should not be reused after shutdown /// Shut down the Liana daemon. pub fn shutdown(self) { self.bitcoin_poller.stop(); } + /// Tell the daemon to shut down. This will return before the shutdown completes. The structure + /// must not be reused after triggering shutdown. + pub fn trigger_shutdown(&self) { + self.bitcoin_poller.trigger_stop() + } + + /// Whether the daemon has finished shutting down. + pub fn shutdown_complete(&self) -> bool { + self.bitcoin_poller.is_stopped() + } + // We need a shutdown utility that does not move for implementing Drop for the DummyLiana #[cfg(test)] pub fn test_shutdown(&mut self) {