[refactor] Prepare for g_signals de-globalization

To this end move some functions into the CMainSignals class.
pull/28960/head
TheCharlatan 10 months ago
parent 3fba3d5dee
commit 473dd4b97a
No known key found for this signature in database
GPG Key ID: 9B79B45691DB4173

@ -96,6 +96,10 @@ public:
static CMainSignals g_signals; static CMainSignals g_signals;
CMainSignals::CMainSignals() {}
CMainSignals::~CMainSignals() {}
void CMainSignals::RegisterBackgroundSignalScheduler(CScheduler& scheduler) void CMainSignals::RegisterBackgroundSignalScheduler(CScheduler& scheduler)
{ {
assert(!m_internals); assert(!m_internals);
@ -125,46 +129,46 @@ CMainSignals& GetMainSignals()
return g_signals; return g_signals;
} }
void RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks) void CMainSignals::RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks)
{ {
// Each connection captures the shared_ptr to ensure that each callback is // Each connection captures the shared_ptr to ensure that each callback is
// executed before the subscriber is destroyed. For more details see #18338. // 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 // Create a shared_ptr with a no-op deleter - CValidationInterface lifecycle
// is managed by the caller. // is managed by the caller.
RegisterSharedValidationInterface({callbacks, [](CValidationInterface*){}}); RegisterSharedValidationInterface({callbacks, [](CValidationInterface*){}});
} }
void UnregisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks) void CMainSignals::UnregisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks)
{ {
UnregisterValidationInterface(callbacks.get()); UnregisterValidationInterface(callbacks.get());
} }
void UnregisterValidationInterface(CValidationInterface* callbacks) void CMainSignals::UnregisterValidationInterface(CValidationInterface* callbacks)
{ {
if (g_signals.m_internals) { if (m_internals) {
g_signals.m_internals->Unregister(callbacks); m_internals->Unregister(callbacks);
} }
} }
void UnregisterAllValidationInterfaces() void CMainSignals::UnregisterAllValidationInterfaces()
{ {
if (!g_signals.m_internals) { if (!m_internals) {
return; return;
} }
g_signals.m_internals->Clear(); m_internals->Clear();
} }
void CallFunctionInValidationInterfaceQueue(std::function<void()> func) void CMainSignals::CallFunctionInValidationInterfaceQueue(std::function<void()> 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); AssertLockNotHeld(cs_main);
// Block until the validation queue drains // 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()); LOG_EVENT("%s: block hash=%s", __func__, block->GetHash().ToString());
m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.NewPoWValidBlock(pindex, block); }); 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<CValidationInterface> callbacks)
{
GetMainSignals().RegisterSharedValidationInterface(callbacks);
}
void UnregisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks)
{
GetMainSignals().UnregisterSharedValidationInterface(callbacks);
}
void CallFunctionInValidationInterfaceQueue(std::function<void ()> func)
{
GetMainSignals().CallFunctionInValidationInterfaceQueue(func);
}
void SyncWithValidationInterfaceQueue()
{
GetMainSignals().SyncWithValidationInterfaceQueue();
}

@ -6,13 +6,16 @@
#ifndef BITCOIN_VALIDATIONINTERFACE_H #ifndef BITCOIN_VALIDATIONINTERFACE_H
#define BITCOIN_VALIDATIONINTERFACE_H #define BITCOIN_VALIDATIONINTERFACE_H
#include <kernel/cs_main.h>
#include <kernel/chain.h> #include <kernel/chain.h>
#include <kernel/cs_main.h>
#include <primitives/transaction.h> // CTransaction(Ref) #include <primitives/transaction.h> // CTransaction(Ref)
#include <sync.h> #include <sync.h>
#include <cstddef>
#include <cstdint>
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <vector>
class BlockValidationState; class BlockValidationState;
class CBlock; class CBlock;
@ -24,41 +27,14 @@ enum class MemPoolRemovalReason;
struct RemovedMempoolTransactionInfo; struct RemovedMempoolTransactionInfo;
struct NewMempoolTransactionInfo; struct NewMempoolTransactionInfo;
/** Register subscriber */
void RegisterValidationInterface(CValidationInterface* callbacks); 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); void UnregisterValidationInterface(CValidationInterface* callbacks);
/** Unregister all subscribers */
void UnregisterAllValidationInterfaces(); 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<CValidationInterface> callbacks); void RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks);
/** Unregister subscriber */
void UnregisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks); void UnregisterSharedValidationInterface(std::shared_ptr<CValidationInterface> 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<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() LOCKS_EXCLUDED(cs_main); void SyncWithValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main);
/** /**
@ -194,12 +170,10 @@ class CMainSignals {
private: private:
std::unique_ptr<MainSignalsImpl> m_internals; std::unique_ptr<MainSignalsImpl> m_internals;
friend void ::RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface>);
friend void ::UnregisterValidationInterface(CValidationInterface*);
friend void ::UnregisterAllValidationInterfaces();
friend void ::CallFunctionInValidationInterfaceQueue(std::function<void ()> func);
public: public:
CMainSignals();
~CMainSignals();
/** Register a CScheduler to give callbacks which should run in the background (may only be called once) */ /** Register a CScheduler to give callbacks which should run in the background (may only be called once) */
void RegisterBackgroundSignalScheduler(CScheduler& scheduler); void RegisterBackgroundSignalScheduler(CScheduler& scheduler);
/** Unregister a CScheduler to give callbacks which should run in the background - these callbacks will now be dropped! */ /** 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(); 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<CValidationInterface> callbacks);
/** Unregister subscriber */
void UnregisterSharedValidationInterface(std::shared_ptr<CValidationInterface> 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<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() LOCKS_EXCLUDED(cs_main);
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload); void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload);
void TransactionAddedToMempool(const NewMempoolTransactionInfo&, uint64_t mempool_sequence); void TransactionAddedToMempool(const NewMempoolTransactionInfo&, uint64_t mempool_sequence);

Loading…
Cancel
Save