refactor: Use wait_for predicate to check for interrupt

Also use uint256::ZERO where appropriate for self-documenting code.
This commit is contained in:
MarcoFalke 2024-09-25 10:08:22 +02:00
parent 5ca28ef28b
commit fa7f52af1a
No known key found for this signature in database
3 changed files with 9 additions and 13 deletions

View file

@ -61,7 +61,8 @@ public:
virtual std::optional<BlockRef> getTip() = 0; virtual std::optional<BlockRef> getTip() = 0;
/** /**
* Waits for the tip to change * Waits for the connected tip to change. If the tip was not connected on
* startup, this will wait.
* *
* @param[in] current_tip block hash of the current chain tip. Function waits * @param[in] current_tip block hash of the current chain tip. Function waits
* for the chain tip to differ from this. * for the chain tip to differ from this.

View file

@ -940,19 +940,12 @@ public:
BlockRef waitTipChanged(uint256 current_tip, MillisecondsDouble timeout) override BlockRef waitTipChanged(uint256 current_tip, MillisecondsDouble timeout) override
{ {
// Interrupt check interval if (timeout > std::chrono::years{100}) timeout = std::chrono::years{100}; // Upper bound to avoid UB in std::chrono
const MillisecondsDouble tick{1000};
auto now{std::chrono::steady_clock::now()};
auto deadline = now + timeout;
// std::chrono does not check against overflow
if (deadline < now) deadline = std::chrono::steady_clock::time_point::max();
{ {
WAIT_LOCK(notifications().m_tip_block_mutex, lock); WAIT_LOCK(notifications().m_tip_block_mutex, lock);
while ((notifications().m_tip_block == uint256() || notifications().m_tip_block == current_tip) && !chainman().m_interrupt) { notifications().m_tip_block_cv.wait_for(lock, timeout, [&]() EXCLUSIVE_LOCKS_REQUIRED(notifications().m_tip_block_mutex) {
now = std::chrono::steady_clock::now(); return (notifications().m_tip_block != current_tip && notifications().m_tip_block != uint256::ZERO) || chainman().m_interrupt;
if (now >= deadline) break; });
notifications().m_tip_block_cv.wait_until(lock, std::min(deadline, now + tick));
}
} }
// Must release m_tip_block_mutex before locking cs_main, to avoid deadlocks. // Must release m_tip_block_mutex before locking cs_main, to avoid deadlocks.
LOCK(::cs_main); LOCK(::cs_main);

View file

@ -57,7 +57,9 @@ public:
Mutex m_tip_block_mutex; Mutex m_tip_block_mutex;
std::condition_variable m_tip_block_cv GUARDED_BY(m_tip_block_mutex); std::condition_variable m_tip_block_cv GUARDED_BY(m_tip_block_mutex);
//! The block for which the last blockTip notification was received for. //! The block for which the last blockTip notification was received for.
uint256 m_tip_block GUARDED_BY(m_tip_block_mutex); //! The initial ZERO means that no block has been connected yet, which may
//! be true even long after startup, until shutdown.
uint256 m_tip_block GUARDED_BY(m_tip_block_mutex){uint256::ZERO};
private: private:
const std::function<bool()>& m_shutdown_request; const std::function<bool()>& m_shutdown_request;