Auto merge of #4390 - daira:fix-chaintip-race-condition, r=ebfull
Fix race conditions during init Fix race conditions due to accessing `chainActive.Tip()` during init, and other minor cleanups. Includes backport of https://github.com/bitcoin/bitcoin/pull/8063 .
This commit is contained in:
commit
5a626317c7
34
src/init.cpp
34
src/init.cpp
|
@ -869,6 +869,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
}
|
||||
|
||||
// Clean shutdown on SIGTERM
|
||||
assert(fRequestShutdown.is_lock_free());
|
||||
struct sigaction sa;
|
||||
sa.sa_handler = HandleSIGTERM;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
|
@ -877,6 +878,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
sigaction(SIGINT, &sa, NULL);
|
||||
|
||||
// Reopen debug.log on SIGHUP
|
||||
assert(fReopenDebugLog.is_lock_free());
|
||||
struct sigaction sa_hup;
|
||||
sa_hup.sa_handler = HandleSIGHUP;
|
||||
sigemptyset(&sa_hup.sa_mask);
|
||||
|
@ -1570,10 +1572,17 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
// original value of chainActive.Tip(), which corresponds with the wallet's
|
||||
// view of the chaintip, is passed to ThreadNotifyWallets before the chain
|
||||
// tip changes again.
|
||||
boost::function<void()> threadnotifywallets = boost::bind(&ThreadNotifyWallets, chainActive.Tip());
|
||||
threadGroup.create_thread(
|
||||
boost::bind(&TraceThread<boost::function<void()>>, "txnotify", threadnotifywallets)
|
||||
);
|
||||
{
|
||||
CBlockIndex *pindexLastTip;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
pindexLastTip = chainActive.Tip();
|
||||
}
|
||||
boost::function<void()> threadnotifywallets = boost::bind(&ThreadNotifyWallets, pindexLastTip);
|
||||
threadGroup.create_thread(
|
||||
boost::bind(&TraceThread<boost::function<void()>>, "txnotify", threadnotifywallets)
|
||||
);
|
||||
}
|
||||
|
||||
// ********************************************************* Step 9: data directory maintenance
|
||||
|
||||
|
@ -1609,10 +1618,21 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
vImportFiles.push_back(strFile);
|
||||
}
|
||||
threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles));
|
||||
if (chainActive.Tip() == NULL) {
|
||||
LogPrintf("Waiting for genesis block to be imported...\n");
|
||||
while (!fRequestShutdown && chainActive.Tip() == NULL)
|
||||
|
||||
// Wait for genesis block to be processed
|
||||
bool fHaveGenesis = false;
|
||||
while (!fHaveGenesis && !fRequestShutdown) {
|
||||
{
|
||||
LOCK(cs_main);
|
||||
fHaveGenesis = (chainActive.Tip() != NULL);
|
||||
}
|
||||
|
||||
if (!fHaveGenesis) {
|
||||
MilliSleep(10);
|
||||
}
|
||||
}
|
||||
if (!fHaveGenesis) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ********************************************************* Step 11: start node
|
||||
|
|
|
@ -43,6 +43,8 @@ int64_t GetTimeMicros()
|
|||
|
||||
void MilliSleep(int64_t n)
|
||||
{
|
||||
// This is defined to be an interruption point.
|
||||
// <https://www.boost.org/doc/libs/1_70_0/doc/html/thread/thread_management.html#interruption_points>
|
||||
boost::this_thread::sleep_for(boost::chrono::milliseconds(n));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue