From def4016171e190e75b5f04430b56dfb9686c2f27 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 15 Mar 2019 19:08:22 +0000 Subject: [PATCH] miner: fix race when stopping mining with start mining enabled --- src/cryptonote_basic/miner.cpp | 15 +++++++++------ src/cryptonote_basic/miner.h | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp index 4e2edc20f..f526efa8e 100644 --- a/src/cryptonote_basic/miner.cpp +++ b/src/cryptonote_basic/miner.cpp @@ -106,6 +106,7 @@ namespace cryptonote m_thread_index(0), m_phandler(phandler), m_height(0), + m_threads_active(0), m_pausers_count(0), m_threads_total(0), m_starter_nonce(0), @@ -264,8 +265,8 @@ namespace cryptonote { CRITICAL_REGION_LOCAL(m_threads_lock); boost::interprocess::ipcdetail::atomic_write32(&m_stop, 1); - for(boost::thread& th: m_threads) - th.join(); + while (m_threads_active > 0) + misc_utils::sleep_no_w(100); m_threads.clear(); } boost::interprocess::ipcdetail::atomic_write32(&m_stop, 0); @@ -447,10 +448,11 @@ namespace cryptonote // In case background mining was active and the miner threads are waiting // on the background miner to signal start. - m_is_background_mining_started_cond.notify_all(); - - for(boost::thread& th: m_threads) - th.join(); + while (m_threads_active > 0) + { + m_is_background_mining_started_cond.notify_all(); + misc_utils::sleep_no_w(100); + } // The background mining thread could be sleeping for a long time, so we // interrupt it just in case @@ -589,6 +591,7 @@ namespace cryptonote } slow_hash_free_state(); MGINFO("Miner thread stopped ["<< th_local_index << "]"); + --m_threads_active; return true; } //----------------------------------------------------------------------------------------------------- diff --git a/src/cryptonote_basic/miner.h b/src/cryptonote_basic/miner.h index 08b1bd7f1..bbb576fff 100644 --- a/src/cryptonote_basic/miner.h +++ b/src/cryptonote_basic/miner.h @@ -125,6 +125,7 @@ namespace cryptonote uint64_t m_height; volatile uint32_t m_thread_index; volatile uint32_t m_threads_total; + std::atomic m_threads_active; std::atomic m_pausers_count; epee::critical_section m_miners_count_lock;