Skip to content

Commit 3448907

Browse files
committed
Merge #12266: Move scheduler/threadGroup into common-init instead of per-app
082a61c Move scheduler/threadGroup into common-init instead of per-app (Matt Corallo) Pull request description: This resolves #12229 which pointed out a shutdown deadlock due to scheduler/checkqueue having been shut down while network message processing is still running. Tree-SHA512: 0c0a76113996b164b0610d3b8c40b396f3e384d165bf098768e31fe3701b00763d0d810ef24702387e2e936fefb9fb900a6225f7417bb0175b585f365d542660
2 parents 7936446 + 082a61c commit 3448907

File tree

4 files changed

+22
-27
lines changed

4 files changed

+22
-27
lines changed

src/bitcoind.cpp

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include <rpc/server.h>
1515
#include <init.h>
1616
#include <noui.h>
17-
#include <scheduler.h>
1817
#include <util.h>
1918
#include <httpserver.h>
2019
#include <httprpc.h>
@@ -40,7 +39,7 @@
4039
* Use the buttons <code>Namespaces</code>, <code>Classes</code> or <code>Files</code> at the top of the page to start navigating the code.
4140
*/
4241

43-
void WaitForShutdown(boost::thread_group* threadGroup)
42+
void WaitForShutdown()
4443
{
4544
bool fShutdown = ShutdownRequested();
4645
// Tell the main threads to shutdown.
@@ -49,11 +48,7 @@ void WaitForShutdown(boost::thread_group* threadGroup)
4948
MilliSleep(200);
5049
fShutdown = ShutdownRequested();
5150
}
52-
if (threadGroup)
53-
{
54-
Interrupt(*threadGroup);
55-
threadGroup->join_all();
56-
}
51+
Interrupt();
5752
}
5853

5954
//////////////////////////////////////////////////////////////////////////////
@@ -62,9 +57,6 @@ void WaitForShutdown(boost::thread_group* threadGroup)
6257
//
6358
bool AppInit(int argc, char* argv[])
6459
{
65-
boost::thread_group threadGroup;
66-
CScheduler scheduler;
67-
6860
bool fRet = false;
6961

7062
//
@@ -165,7 +157,7 @@ bool AppInit(int argc, char* argv[])
165157
// If locking the data directory failed, exit immediately
166158
return false;
167159
}
168-
fRet = AppInitMain(threadGroup, scheduler);
160+
fRet = AppInitMain();
169161
}
170162
catch (const std::exception& e) {
171163
PrintExceptionContinue(&e, "AppInit()");
@@ -175,10 +167,9 @@ bool AppInit(int argc, char* argv[])
175167

176168
if (!fRet)
177169
{
178-
Interrupt(threadGroup);
179-
threadGroup.join_all();
170+
Interrupt();
180171
} else {
181-
WaitForShutdown(&threadGroup);
172+
WaitForShutdown();
182173
}
183174
Shutdown();
184175

src/init.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,10 @@ class CCoinsViewErrorCatcher final : public CCoinsViewBacked
155155
static std::unique_ptr<CCoinsViewErrorCatcher> pcoinscatcher;
156156
static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
157157

158-
void Interrupt(boost::thread_group& threadGroup)
158+
static boost::thread_group threadGroup;
159+
static CScheduler scheduler;
160+
161+
void Interrupt()
159162
{
160163
InterruptHTTPServer();
161164
InterruptHTTPRPC();
@@ -164,7 +167,6 @@ void Interrupt(boost::thread_group& threadGroup)
164167
InterruptTorControl();
165168
if (g_connman)
166169
g_connman->Interrupt();
167-
threadGroup.interrupt_all();
168170
}
169171

170172
void Shutdown()
@@ -199,6 +201,12 @@ void Shutdown()
199201
g_connman.reset();
200202

201203
StopTorControl();
204+
205+
// After everything has been shut down, but before things get flushed, stop the
206+
// CScheduler/checkqueue threadGroup
207+
threadGroup.interrupt_all();
208+
threadGroup.join_all();
209+
202210
if (fDumpMempoolLater && gArgs.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
203211
DumpMempool();
204212
}
@@ -705,7 +713,7 @@ bool InitSanityCheck(void)
705713
return true;
706714
}
707715

708-
bool AppInitServers(boost::thread_group& threadGroup)
716+
bool AppInitServers()
709717
{
710718
RPCServer::OnStarted(&OnRPCStarted);
711719
RPCServer::OnStopped(&OnRPCStopped);
@@ -1190,7 +1198,7 @@ bool AppInitLockDataDirectory()
11901198
return true;
11911199
}
11921200

1193-
bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
1201+
bool AppInitMain()
11941202
{
11951203
const CChainParams& chainparams = Params();
11961204
// ********************************************************* Step 4a: application initialization
@@ -1257,7 +1265,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
12571265
if (gArgs.GetBoolArg("-server", false))
12581266
{
12591267
uiInterface.InitMessage.connect(SetRPCWarmupStatus);
1260-
if (!AppInitServers(threadGroup))
1268+
if (!AppInitServers())
12611269
return InitError(_("Unable to start HTTP server. See debug log for details."));
12621270
}
12631271

src/init.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class thread_group;
1919
void StartShutdown();
2020
bool ShutdownRequested();
2121
/** Interrupt threads */
22-
void Interrupt(boost::thread_group& threadGroup);
22+
void Interrupt();
2323
void Shutdown();
2424
//!Initialize the logging infrastructure
2525
void InitLogging();
@@ -54,7 +54,7 @@ bool AppInitLockDataDirectory();
5454
* @note This should only be done after daemonization. Call Shutdown() if this function fails.
5555
* @pre Parameters should be parsed and config file should be read, AppInitLockDataDirectory should have been called.
5656
*/
57-
bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler);
57+
bool AppInitMain();
5858

5959
/** The help message mode determines what help message to show */
6060
enum HelpMessageMode {

src/qt/bitcoin.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828

2929
#include <init.h>
3030
#include <rpc/server.h>
31-
#include <scheduler.h>
3231
#include <ui_interface.h>
3332
#include <util.h>
3433
#include <warnings.h>
@@ -193,8 +192,6 @@ public Q_SLOTS:
193192
void runawayException(const QString &message);
194193

195194
private:
196-
boost::thread_group threadGroup;
197-
CScheduler scheduler;
198195

199196
/// Pass fatal exception message to UI thread
200197
void handleRunawayException(const std::exception *e);
@@ -300,7 +297,7 @@ void BitcoinCore::initialize()
300297
try
301298
{
302299
qDebug() << __func__ << ": Running initialization in thread";
303-
bool rv = AppInitMain(threadGroup, scheduler);
300+
bool rv = AppInitMain();
304301
Q_EMIT initializeResult(rv);
305302
} catch (const std::exception& e) {
306303
handleRunawayException(&e);
@@ -314,8 +311,7 @@ void BitcoinCore::shutdown()
314311
try
315312
{
316313
qDebug() << __func__ << ": Running Shutdown in thread";
317-
Interrupt(threadGroup);
318-
threadGroup.join_all();
314+
Interrupt();
319315
Shutdown();
320316
qDebug() << __func__ << ": Shutdown finished";
321317
Q_EMIT shutdownResult();

0 commit comments

Comments
 (0)