diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index 5e944a7c47d..91ab34d365e 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -96,6 +96,10 @@ public: static CMainSignals g_signals; +CMainSignals::CMainSignals() {} + +CMainSignals::~CMainSignals() {} + void CMainSignals::RegisterBackgroundSignalScheduler(CScheduler& scheduler) { assert(!m_internals); @@ -125,46 +129,46 @@ CMainSignals& GetMainSignals() return g_signals; } -void RegisterSharedValidationInterface(std::shared_ptr callbacks) +void CMainSignals::RegisterSharedValidationInterface(std::shared_ptr callbacks) { // Each connection captures the shared_ptr to ensure that each callback is // executed before the subscriber is destroyed. For more details see #18338. - g_signals.m_internals->Register(std::move(callbacks)); + m_internals->Register(std::move(callbacks)); } -void RegisterValidationInterface(CValidationInterface* callbacks) +void CMainSignals::RegisterValidationInterface(CValidationInterface* callbacks) { // Create a shared_ptr with a no-op deleter - CValidationInterface lifecycle // is managed by the caller. RegisterSharedValidationInterface({callbacks, [](CValidationInterface*){}}); } -void UnregisterSharedValidationInterface(std::shared_ptr callbacks) +void CMainSignals::UnregisterSharedValidationInterface(std::shared_ptr callbacks) { UnregisterValidationInterface(callbacks.get()); } -void UnregisterValidationInterface(CValidationInterface* callbacks) +void CMainSignals::UnregisterValidationInterface(CValidationInterface* callbacks) { - if (g_signals.m_internals) { - g_signals.m_internals->Unregister(callbacks); + if (m_internals) { + m_internals->Unregister(callbacks); } } -void UnregisterAllValidationInterfaces() +void CMainSignals::UnregisterAllValidationInterfaces() { - if (!g_signals.m_internals) { + if (!m_internals) { return; } - g_signals.m_internals->Clear(); + m_internals->Clear(); } -void CallFunctionInValidationInterfaceQueue(std::function func) +void CMainSignals::CallFunctionInValidationInterfaceQueue(std::function func) { - g_signals.m_internals->m_schedulerClient.AddToProcessQueue(std::move(func)); + m_internals->m_schedulerClient.AddToProcessQueue(std::move(func)); } -void SyncWithValidationInterfaceQueue() +void CMainSignals::SyncWithValidationInterfaceQueue() { AssertLockNotHeld(cs_main); // Block until the validation queue drains @@ -273,3 +277,33 @@ void CMainSignals::NewPoWValidBlock(const CBlockIndex *pindex, const std::shared LOG_EVENT("%s: block hash=%s", __func__, block->GetHash().ToString()); m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.NewPoWValidBlock(pindex, block); }); } + +// These functions are temporary and will be removed in the following commit +void RegisterValidationInterface(CValidationInterface* callbacks) +{ + GetMainSignals().RegisterValidationInterface(callbacks); +} +void UnregisterValidationInterface(CValidationInterface* callbacks) +{ + GetMainSignals().UnregisterValidationInterface(callbacks); +} +void UnregisterAllValidationInterfaces() +{ + GetMainSignals().UnregisterAllValidationInterfaces(); +} +void RegisterSharedValidationInterface(std::shared_ptr callbacks) +{ + GetMainSignals().RegisterSharedValidationInterface(callbacks); +} +void UnregisterSharedValidationInterface(std::shared_ptr callbacks) +{ + GetMainSignals().UnregisterSharedValidationInterface(callbacks); +} +void CallFunctionInValidationInterfaceQueue(std::function func) +{ + GetMainSignals().CallFunctionInValidationInterfaceQueue(func); +} +void SyncWithValidationInterfaceQueue() +{ + GetMainSignals().SyncWithValidationInterfaceQueue(); +} diff --git a/src/validationinterface.h b/src/validationinterface.h index d9292ae2c96..0cd494233a9 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -6,13 +6,16 @@ #ifndef BITCOIN_VALIDATIONINTERFACE_H #define BITCOIN_VALIDATIONINTERFACE_H -#include #include +#include #include // CTransaction(Ref) #include +#include +#include #include #include +#include class BlockValidationState; class CBlock; @@ -24,41 +27,14 @@ enum class MemPoolRemovalReason; struct RemovedMempoolTransactionInfo; struct NewMempoolTransactionInfo; -/** Register subscriber */ void RegisterValidationInterface(CValidationInterface* callbacks); -/** Unregister subscriber. DEPRECATED. This is not safe to use when the RPC server or main message handler thread is running. */ void UnregisterValidationInterface(CValidationInterface* callbacks); -/** Unregister all subscribers */ void UnregisterAllValidationInterfaces(); -// Alternate registration functions that release a shared_ptr after the last -// notification is sent. These are useful for race-free cleanup, since -// unregistration is nonblocking and can return before the last notification is -// processed. -/** Register subscriber */ void RegisterSharedValidationInterface(std::shared_ptr callbacks); -/** Unregister subscriber */ void UnregisterSharedValidationInterface(std::shared_ptr callbacks); -/** - * 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); -/** - * This is a synonym for the following, which asserts certain locks are not - * held: - * std::promise promise; - * CallFunctionInValidationInterfaceQueue([&promise] { - * promise.set_value(); - * }); - * promise.get_future().wait(); - */ void SyncWithValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main); /** @@ -194,12 +170,10 @@ class CMainSignals { private: std::unique_ptr m_internals; - friend void ::RegisterSharedValidationInterface(std::shared_ptr); - friend void ::UnregisterValidationInterface(CValidationInterface*); - friend void ::UnregisterAllValidationInterfaces(); - friend void ::CallFunctionInValidationInterfaceQueue(std::function func); - public: + CMainSignals(); + ~CMainSignals(); + /** Register a CScheduler to give callbacks which should run in the background (may only be called once) */ void RegisterBackgroundSignalScheduler(CScheduler& scheduler); /** Unregister a CScheduler to give callbacks which should run in the background - these callbacks will now be dropped! */ @@ -209,6 +183,43 @@ public: size_t CallbacksPending(); + /** Register subscriber */ + void RegisterValidationInterface(CValidationInterface* callbacks); + /** Unregister subscriber. DEPRECATED. This is not safe to use when the RPC server or main message handler thread is running. */ + void UnregisterValidationInterface(CValidationInterface* callbacks); + /** Unregister all subscribers */ + void UnregisterAllValidationInterfaces(); + + // Alternate registration functions that release a shared_ptr after the last + // notification is sent. These are useful for race-free cleanup, since + // unregistration is nonblocking and can return before the last notification is + // processed. + /** Register subscriber */ + void RegisterSharedValidationInterface(std::shared_ptr callbacks); + /** Unregister subscriber */ + void UnregisterSharedValidationInterface(std::shared_ptr callbacks); + + /** + * 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); + + /** + * This is a synonym for the following, which asserts certain locks are not + * held: + * std::promise promise; + * CallFunctionInValidationInterfaceQueue([&promise] { + * promise.set_value(); + * }); + * promise.get_future().wait(); + */ + void SyncWithValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main); void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload); void TransactionAddedToMempool(const NewMempoolTransactionInfo&, uint64_t mempool_sequence);