Acquire CCheckQueue's lock to avoid race condition
authorMASM fan <masmfan@gmail.com>
Wed, 11 Feb 2015 18:15:42 +0000 (10:15 -0800)
committerMASM fan <masmfan@gmail.com>
Wed, 11 Feb 2015 18:15:42 +0000 (10:15 -0800)
src/checkqueue.h
src/init.cpp
src/main.cpp
src/main.h

index 0ae4020..3c30db7 100644 (file)
@@ -165,7 +165,15 @@ public:
             condQuit.wait(lock);
     }
 
-    friend class CCheckQueueControl<T>;
+    ~CCheckQueue() {
+        Quit();
+    }
+
+    bool IsIdle()
+    {
+        boost::unique_lock<boost::mutex> 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<T> *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);
         }
     }
 
index 296369d..b1dec89 100644 (file)
@@ -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.
index 9370ffa..2a97e49 100644 (file)
@@ -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)
index b553d6c..c6e6558 100644 (file)
@@ -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);