diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -17,7 +17,6 @@ #include "init.h" #include "noui.h" #include "rpc/server.h" -#include "scheduler.h" #include "util.h" #include "utilstrencodings.h" #if ENABLE_WALLET @@ -50,14 +49,11 @@ * Files at the top of the page to start navigating the code. */ -void WaitForShutdown(boost::thread_group *threadGroup) { +void WaitForShutdown() { while (!ShutdownRequested()) { MilliSleep(200); } - if (threadGroup) { - Interrupt(*threadGroup); - threadGroup->join_all(); - } + Interrupt(); } ////////////////////////////////////////////////////////////////////////////// @@ -65,9 +61,6 @@ // Start // bool AppInit(int argc, char *argv[]) { - boost::thread_group threadGroup; - CScheduler scheduler; - // FIXME: Ideally, we'd like to build the config here, but that's currently // not possible as the whole application has too many global state. However, // this is a first step. @@ -189,8 +182,7 @@ // If locking the data directory failed, exit immediately exit(EXIT_FAILURE); } - fRet = AppInitMain(config, httpRPCRequestProcessor, threadGroup, - scheduler); + fRet = AppInitMain(config, httpRPCRequestProcessor); } catch (const std::exception &e) { PrintExceptionContinue(&e, "AppInit()"); } catch (...) { @@ -198,13 +190,9 @@ } if (!fRet) { - Interrupt(threadGroup); - // threadGroup.join_all(); was left out intentionally here, because we - // didn't re-test all of the startup-failure cases to make sure they - // don't result in a hang due to some - // thread-blocking-waiting-for-another-thread-during-startup case. + Interrupt(); } else { - WaitForShutdown(&threadGroup); + WaitForShutdown(); } Shutdown(); diff --git a/src/init.h b/src/init.h --- a/src/init.h +++ b/src/init.h @@ -26,7 +26,7 @@ void StartShutdown(); bool ShutdownRequested(); /** Interrupt threads */ -void Interrupt(boost::thread_group &threadGroup); +void Interrupt(); void Shutdown(); //! Initialize the logging infrastructure void InitLogging(); @@ -71,8 +71,7 @@ * AppInitLockDataDirectory should have been called. */ bool AppInitMain(Config &config, - HTTPRPCRequestProcessor &httpRPCRequestProcessor, - boost::thread_group &threadGroup, CScheduler &scheduler); + HTTPRPCRequestProcessor &httpRPCRequestProcessor); /** The help message mode determines what help message to show */ enum HelpMessageMode { HMM_BITCOIND, HMM_BITCOIN_QT }; diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -159,7 +159,10 @@ static std::unique_ptr pcoinscatcher; static std::unique_ptr globalVerifyHandle; -void Interrupt(boost::thread_group &threadGroup) { +static boost::thread_group threadGroup; +static CScheduler scheduler; + +void Interrupt() { InterruptHTTPServer(); InterruptHTTPRPC(); InterruptRPC(); @@ -169,7 +172,6 @@ if (g_connman) { g_connman->Interrupt(); } - threadGroup.interrupt_all(); } void Shutdown() { @@ -202,6 +204,12 @@ g_connman.reset(); StopTorControl(); + + // After everything has been shut down, but before things get flushed, stop + // the CScheduler/checkqueue threadGroup + threadGroup.interrupt_all(); + threadGroup.join_all(); + if (fDumpMempoolLater && gArgs.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) { DumpMempool(); @@ -1107,8 +1115,7 @@ } static bool AppInitServers(Config &config, - HTTPRPCRequestProcessor &httpRPCRequestProcessor, - boost::thread_group &threadGroup) { + HTTPRPCRequestProcessor &httpRPCRequestProcessor) { RPCServerSignals::OnStarted(&OnRPCStarted); RPCServerSignals::OnStopped(&OnRPCStopped); if (!InitHTTPServer(config)) { @@ -1733,8 +1740,7 @@ } bool AppInitMain(Config &config, - HTTPRPCRequestProcessor &httpRPCRequestProcessor, - boost::thread_group &threadGroup, CScheduler &scheduler) { + HTTPRPCRequestProcessor &httpRPCRequestProcessor) { // Step 4a: application initialization const CChainParams &chainparams = config.GetChainParams(); @@ -1796,7 +1802,7 @@ */ if (gArgs.GetBoolArg("-server", false)) { uiInterface.InitMessage.connect(SetRPCWarmupStatus); - if (!AppInitServers(config, httpRPCRequestProcessor, threadGroup)) { + if (!AppInitServers(config, httpRPCRequestProcessor)) { return InitError( _("Unable to start HTTP server. See debug log for details.")); } diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -29,7 +29,6 @@ #include "init.h" #include "rpc/server.h" -#include "scheduler.h" #include "ui_interface.h" #include "uint256.h" #include "util.h" @@ -195,9 +194,6 @@ void runawayException(const QString &message); private: - boost::thread_group threadGroup; - CScheduler scheduler; - /// Pass fatal exception message to UI thread void handleRunawayException(const std::exception *e); }; @@ -297,8 +293,7 @@ Config &config(*cfg); try { qDebug() << __func__ << ": Running initialization in thread"; - bool rv = AppInitMain(config, *httpRPCRequestProcessor, threadGroup, - scheduler); + bool rv = AppInitMain(config, *httpRPCRequestProcessor); Q_EMIT initializeResult(rv); } catch (const std::exception &e) { handleRunawayException(&e); @@ -310,8 +305,7 @@ void BitcoinABC::shutdown() { try { qDebug() << __func__ << ": Running Shutdown in thread"; - Interrupt(threadGroup); - threadGroup.join_all(); + Interrupt(); Shutdown(); qDebug() << __func__ << ": Shutdown finished"; Q_EMIT shutdownResult();