From 0b2f42d7376c5f7c1ba1ac5d17a30691989d9159 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 8 Jun 2017 11:13:46 -0400 Subject: [PATCH] Add CallFunctionInQueue to wait on validation interface queue drain --- src/validationinterface.cpp | 4 ++++ src/validationinterface.h | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index b4efbe6ef3..f2b35d5627 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -104,6 +104,10 @@ void UnregisterAllValidationInterfaces() { g_signals.m_internals->NewPoWValidBlock.disconnect_all_slots(); } +void CallFunctionInValidationInterfaceQueue(std::function func) { + g_signals.m_internals->m_schedulerClient.AddToProcessQueue(std::move(func)); +} + void CMainSignals::MempoolEntryRemoved(CTransactionRef ptx, MemPoolRemovalReason reason) { if (reason != MemPoolRemovalReason::BLOCK && reason != MemPoolRemovalReason::CONFLICT) { m_internals->m_schedulerClient.AddToProcessQueue([ptx, this] { diff --git a/src/validationinterface.h b/src/validationinterface.h index 9b5784ccc3..1b231e5281 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -6,10 +6,11 @@ #ifndef BITCOIN_VALIDATIONINTERFACE_H #define BITCOIN_VALIDATIONINTERFACE_H -#include - #include "primitives/transaction.h" // CTransaction(Ref) +#include +#include + class CBlock; class CBlockIndex; struct CBlockLocator; @@ -31,6 +32,16 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn); void UnregisterValidationInterface(CValidationInterface* pwalletIn); /** Unregister all wallets from core */ void UnregisterAllValidationInterfaces(); +/** + * Pushes a function to callback onto the notification queue, guaranteeing any + * callbacks generated prior to now are finished when the function is called. + * + * Be very careful blocking on func to be called if any locks are held - + * validation interface clients may not be able to make progress as they often + * wait for things like cs_main, so blocking until func is called with cs_main + * will result in a deadlock (that DEBUG_LOCKORDER will miss). + */ +void CallFunctionInValidationInterfaceQueue(std::function func); class CValidationInterface { protected: @@ -86,6 +97,7 @@ private: friend void ::RegisterValidationInterface(CValidationInterface*); friend void ::UnregisterValidationInterface(CValidationInterface*); friend void ::UnregisterAllValidationInterfaces(); + friend void ::CallFunctionInValidationInterfaceQueue(std::function func); void MempoolEntryRemoved(CTransactionRef tx, MemPoolRemovalReason reason);