diff options
author | Matt Corallo <git@bluematt.me> | 2017-12-04 18:57:55 -0500 |
---|---|---|
committer | Matt Corallo <git@bluematt.me> | 2017-12-26 11:54:49 -0500 |
commit | 36137497f1e2b3324ca84550f4f295dcd605d1fa (patch) | |
tree | 684bc166f66e54273396034cef46203eff8ca62b /src | |
parent | 5a933cefcc5e0595a1ec46fc5ea287aa163ecd3f (diff) |
Block ActivateBestChain to empty validationinterface queue
Diffstat (limited to 'src')
-rw-r--r-- | src/test/test_bitcoin.cpp | 6 | ||||
-rw-r--r-- | src/validation.cpp | 13 |
2 files changed, 16 insertions, 3 deletions
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index f52c8ccc21..6bd228a63a 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -69,9 +69,9 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha fs::create_directories(pathTemp); gArgs.ForceSetArg("-datadir", pathTemp.string()); - // Note that because we don't bother running a scheduler thread here, - // callbacks via CValidationInterface are unreliable, but that's OK, - // our unit tests aren't testing multiple parts of the code at once. + // We have to run a scheduler thread to prevent ActivateBestChain + // from blocking due to queue overrun. + threadGroup.create_thread(boost::bind(&CScheduler::serviceQueue, &scheduler)); GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); mempool.setSanityCheck(1.0); diff --git a/src/validation.cpp b/src/validation.cpp index 71a51c499c..23ce6509d5 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -40,6 +40,7 @@ #include <validationinterface.h> #include <warnings.h> +#include <future> #include <sstream> #include <boost/algorithm/string/replace.hpp> @@ -2566,6 +2567,18 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams& int nStopAtHeight = gArgs.GetArg("-stopatheight", DEFAULT_STOPATHEIGHT); do { boost::this_thread::interruption_point(); + + if (GetMainSignals().CallbacksPending() > 10) { + // Block until the validation queue drains. This should largely + // never happen in normal operation, however may happen during + // reindex, causing memory blowup if we run too far ahead. + std::promise<void> promise; + CallFunctionInValidationInterfaceQueue([&promise] { + promise.set_value(); + }); + promise.get_future().wait(); + } + if (ShutdownRequested()) break; |