From f94158ea104e435166e6e6074f0d941b903267eb Mon Sep 17 00:00:00 2001 From: MASM fan Date: Wed, 11 Feb 2015 10:15:42 -0800 Subject: [PATCH] Acquire CCheckQueue's lock to avoid race condition --- src/checkqueue.h | 15 +++++++++++---- src/init.cpp | 32 ++++++++++++++++++++++++++++---- src/main.cpp | 12 ++++++++++++ src/main.h | 2 ++ 4 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/checkqueue.h b/src/checkqueue.h index 0ae4020..3c30db7 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -165,7 +165,15 @@ public: condQuit.wait(lock); } - friend class CCheckQueueControl; + ~CCheckQueue() { + Quit(); + } + + bool IsIdle() + { + boost::unique_lock lock(mutex); + return (nTotal == nIdle && nTodo == 0 && fAllOk == true); + } }; /** RAII-style controller object for a CCheckQueue that guarantees the passed @@ -180,9 +188,8 @@ public: CCheckQueueControl(CCheckQueue *pqueueIn) : pqueue(pqueueIn), fDone(false) { // passed queue is supposed to be unused, or NULL if (pqueue != NULL) { - assert(pqueue->nTotal == pqueue->nIdle); - assert(pqueue->nTodo == 0); - assert(pqueue->fAllOk == true); + bool isIdle = pqueue->IsIdle(); + assert(isIdle); } } diff --git a/src/init.cpp b/src/init.cpp index 296369d..b1dec89 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -86,6 +86,7 @@ void Shutdown(void* parg) if (fFirstThread) { fShutdown = true; + fRequestShutdown = true; nTransactionsUpdated++; // CTxDB().Close(); bitdb.Flush(false); @@ -766,12 +767,35 @@ bool AppInit2() return false; } - uiInterface.InitMessage(_("Loading block index...")); + printf("Loading block index...\n"); - nStart = GetTimeMillis(); - if (!LoadBlockIndex()) - return InitError(_("Error loading blkindex.dat")); + bool fLoaded = false; + while (!fLoaded) { + std::string strLoadError; + uiInterface.InitMessage(_("Loading block index...")); + + nStart = GetTimeMillis(); + do { + try { + UnloadBlockIndex(); + + if (!LoadBlockIndex()) { + strLoadError = _("Error loading block database"); + break; + } + } catch(std::exception &e) { + strLoadError = _("Error opening block database"); + break; + } + + fLoaded = true; + } while(false); + if (!fLoaded) { + // TODO: suggest reindex here + return InitError(strLoadError); + } + } // as LoadBlockIndex can take several minutes, it's possible the user // requested to kill bitcoin-qt during the last operation. If so, exit. diff --git a/src/main.cpp b/src/main.cpp index 9370ffa..2a97e49 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2768,6 +2768,18 @@ FILE* AppendBlockFile(unsigned int& nFileRet) } } +void UnloadBlockIndex() +{ + mapBlockIndex.clear(); + setStakeSeen.clear(); + pindexGenesisBlock = NULL; + nBestHeight = 0; + nBestChainTrust = 0; + nBestInvalidTrust = 0; + hashBestChain = 0; + pindexBest = NULL; +} + bool LoadBlockIndex(bool fAllowNew) { if (fTestNet) diff --git a/src/main.h b/src/main.h index b553d6c..c6e6558 100644 --- a/src/main.h +++ b/src/main.h @@ -111,6 +111,8 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock); bool CheckDiskSpace(uint64_t nAdditionalBytes=0); FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); FILE* AppendBlockFile(unsigned int& nFileRet); + +void UnloadBlockIndex(); bool LoadBlockIndex(bool fAllowNew=true); void PrintBlockTree(); CBlockIndex* FindBlockByHeight(int nHeight); -- 1.7.1