From 55a1db4fa2cf62b9766ef382c1e14b3ecbdf67fe Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 15 Apr 2014 17:38:25 +0200 Subject: Solve chainActive-related locking issues - In wallet and GUI code LOCK cs_main as well as cs_wallet when necessary - In main.cpp SendMessages move the TRY_LOCK(cs_main) up, to encompass the call to IsInitialBlockDownload. - Make ActivateBestChain, AddToBlockIndex, IsInitialBlockDownload, InitBlockIndex acquire the cs_main lock Fixes #3997 --- src/main.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 456754353..0bbe83370 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1310,7 +1310,7 @@ int GetNumBlocksOfPeers() bool IsInitialBlockDownload() { - AssertLockHeld(cs_main); + LOCK(cs_main); if (fImporting || fReindex || chainActive.Height() < Checkpoints::GetTotalBlocksEstimate()) return true; static int64_t nLastUpdate; @@ -2087,7 +2087,7 @@ void static FindMostWorkChain() { // Try to activate to the most-work chain (thereby connecting it). bool ActivateBestChain(CValidationState &state) { - AssertLockHeld(cs_main); + LOCK(cs_main); CBlockIndex *pindexOldTip = chainActive.Tip(); bool fComplete = false; while (!fComplete) { @@ -2136,7 +2136,6 @@ bool ActivateBestChain(CValidationState &state) { bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos& pos) { - AssertLockHeld(cs_main); // Check for duplicate uint256 hash = block.GetHash(); if (mapBlockIndex.count(hash)) @@ -2173,6 +2172,7 @@ bool AddToBlockIndex(CBlock& block, CValidationState& state, const CDiskBlockPos if (!ActivateBestChain(state)) return false; + LOCK(cs_main); if (pindexNew == chainActive.Tip()) { // Clear fork warning if its no longer applicable @@ -2962,6 +2962,7 @@ bool LoadBlockIndex() bool InitBlockIndex() { + LOCK(cs_main); // Check whether we're already initialized if (chainActive.Genesis() != NULL) return true; @@ -4201,6 +4202,10 @@ bool SendMessages(CNode* pto, bool fSendTrickle) } } + TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState() + if (!lockMain) + return true; + // Address refresh broadcast static int64_t nLastRebroadcast; if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > 24 * 60 * 60)) @@ -4251,10 +4256,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle) pto->PushMessage("addr", vAddr); } - TRY_LOCK(cs_main, lockMain); - if (!lockMain) - return true; - CNodeState &state = *State(pto->GetId()); if (state.fShouldBan) { if (pto->addr.IsLocal()) -- cgit v1.2.3