Browse Source

Add helper to wait for validation interface queue to catch up

0.16
Matt Corallo 7 years ago
parent
commit
97d2b09c12
  1. 6
      src/validation.cpp
  2. 12
      src/validationinterface.cpp
  3. 10
      src/validationinterface.h
  4. 7
      src/wallet/wallet.cpp

6
src/validation.cpp

@ -2572,11 +2572,7 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
// Block until the validation queue drains. This should largely // Block until the validation queue drains. This should largely
// never happen in normal operation, however may happen during // never happen in normal operation, however may happen during
// reindex, causing memory blowup if we run too far ahead. // reindex, causing memory blowup if we run too far ahead.
std::promise<void> promise; SyncWithValidationInterfaceQueue();
CallFunctionInValidationInterfaceQueue([&promise] {
promise.set_value();
});
promise.get_future().wait();
} }
if (ShutdownRequested()) if (ShutdownRequested())

12
src/validationinterface.cpp

@ -11,9 +11,11 @@
#include <sync.h> #include <sync.h>
#include <txmempool.h> #include <txmempool.h>
#include <util.h> #include <util.h>
#include <validation.h>
#include <list> #include <list>
#include <atomic> #include <atomic>
#include <future>
#include <boost/signals2/signal.hpp> #include <boost/signals2/signal.hpp>
@ -118,6 +120,16 @@ void CallFunctionInValidationInterfaceQueue(std::function<void ()> func) {
g_signals.m_internals->m_schedulerClient.AddToProcessQueue(std::move(func)); g_signals.m_internals->m_schedulerClient.AddToProcessQueue(std::move(func));
} }
void SyncWithValidationInterfaceQueue() {
AssertLockNotHeld(cs_main);
// Block until the validation queue drains
std::promise<void> promise;
CallFunctionInValidationInterfaceQueue([&promise] {
promise.set_value();
});
promise.get_future().wait();
}
void CMainSignals::MempoolEntryRemoved(CTransactionRef ptx, MemPoolRemovalReason reason) { void CMainSignals::MempoolEntryRemoved(CTransactionRef ptx, MemPoolRemovalReason reason) {
if (reason != MemPoolRemovalReason::BLOCK && reason != MemPoolRemovalReason::CONFLICT) { if (reason != MemPoolRemovalReason::BLOCK && reason != MemPoolRemovalReason::CONFLICT) {
m_internals->m_schedulerClient.AddToProcessQueue([ptx, this] { m_internals->m_schedulerClient.AddToProcessQueue([ptx, this] {

10
src/validationinterface.h

@ -42,6 +42,16 @@ void UnregisterAllValidationInterfaces();
* will result in a deadlock (that DEBUG_LOCKORDER will miss). * will result in a deadlock (that DEBUG_LOCKORDER will miss).
*/ */
void CallFunctionInValidationInterfaceQueue(std::function<void ()> func); void CallFunctionInValidationInterfaceQueue(std::function<void ()> func);
/**
* This is a synonym for the following, which asserts certain locks are not
* held:
* std::promise<void> promise;
* CallFunctionInValidationInterfaceQueue([&promise] {
* promise.set_value();
* });
* promise.get_future().wait();
*/
void SyncWithValidationInterfaceQueue();
class CValidationInterface { class CValidationInterface {
protected: protected:

7
src/wallet/wallet.cpp

@ -1292,12 +1292,7 @@ void CWallet::BlockUntilSyncedToCurrentChain() {
// ...otherwise put a callback in the validation interface queue and wait // ...otherwise put a callback in the validation interface queue and wait
// for the queue to drain enough to execute it (indicating we are caught up // for the queue to drain enough to execute it (indicating we are caught up
// at least with the time we entered this function). // at least with the time we entered this function).
SyncWithValidationInterfaceQueue();
std::promise<void> promise;
CallFunctionInValidationInterfaceQueue([&promise] {
promise.set_value();
});
promise.get_future().wait();
} }

Loading…
Cancel
Save