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:
Homu 2020-03-16 15:11:43 +00:00
commit 5a626317c7
2 changed files with 29 additions and 7 deletions

View File

@ -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

View File

@ -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));
}