From 6f22dfca11eb9cae620eb58c10b94c020b8fb81d Mon Sep 17 00:00:00 2001 From: SChernykh <15806605+SChernykh@users.noreply.github.com> Date: Sun, 18 Feb 2024 17:46:47 +0100 Subject: [PATCH] Fixed a deadlock on shutdown --- src/merge_mining_client_tari.cpp | 25 ++++++++++++++++++++++--- src/side_chain.cpp | 2 +- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/merge_mining_client_tari.cpp b/src/merge_mining_client_tari.cpp index 02b428d..3c49ce3 100644 --- a/src/merge_mining_client_tari.cpp +++ b/src/merge_mining_client_tari.cpp @@ -93,7 +93,10 @@ MergeMiningClientTari::~MergeMiningClientTari() LOGINFO(1, "stopping"); m_workerStop.exchange(1); - uv_cond_signal(&m_workerCond); + { + MutexLock lock(m_workerLock); + uv_cond_signal(&m_workerCond); + } uv_thread_join(&m_worker); m_server->shutdown_tcp(); @@ -137,7 +140,11 @@ void MergeMiningClientTari::run() { LOGINFO(1, "worker thread ready"); - do { + using namespace std::chrono; + + for (;;) { + const auto t1 = high_resolution_clock::now(); + MutexLock lock(m_workerLock); LOGINFO(6, "Getting new block template from Tari node"); @@ -179,7 +186,17 @@ void MergeMiningClientTari::run() } LOGINFO(6, "Tari height = " << response2.block().header().height()); - } while ((uv_cond_timedwait(&m_workerCond, &m_workerLock, 500'000'000) == UV_ETIMEDOUT) && (m_workerStop.load() == 0)); + + if (m_workerStop.load() != 0) { + return; + } + + const int64_t timeout = std::max(500'000'000 - duration_cast(high_resolution_clock::now() - t1).count(), 1'000'000); + + if (uv_cond_timedwait(&m_workerCond, &m_workerLock, timeout) != UV_ETIMEDOUT) { + return; + } + } } // TariServer and TariClient are simply a proxy from a localhost TCP port to the external Tari node @@ -293,6 +310,8 @@ bool MergeMiningClientTari::TariClient::on_connect() return server->connect_upstream(this); } else { + // The outgoing connection is ready now + // Check if the incoming connection (downstream) has already sent something that needs to be relayed TariClient* downstream = m_pairedClient; downstream->m_pairedClient = this; downstream->m_pairedClientSavedResetCounter = m_resetCounter; diff --git a/src/side_chain.cpp b/src/side_chain.cpp index 38e4956..199c077 100644 --- a/src/side_chain.cpp +++ b/src/side_chain.cpp @@ -2346,8 +2346,8 @@ void SideChain::launch_precalc(const PoolBlock* block) { MutexLock lock2(m_precalcJobsMutex); m_precalcJobs.push_back(job); + uv_cond_signal(&m_precalcJobsCond); } - uv_cond_signal(&m_precalcJobsCond); } } }