Skip to content

Commit

Permalink
let validationinterface take shared_ptr
Browse files Browse the repository at this point in the history
  • Loading branch information
panleone committed Apr 7, 2024
1 parent db78a7e commit b01c3df
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 5 deletions.
18 changes: 15 additions & 3 deletions src/validationinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,11 @@ CMainSignals& GetMainSignals()
{
return g_signals;
}

void RegisterValidationInterface(CValidationInterface* pwalletIn)
void RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface> pwalletIn)
{
ValidationInterfaceConnections& conns = g_signals.m_internals->m_connMainSignals[pwalletIn];
// Each connection captures pwalletIn to ensure that each callback is
// executed before pwalletIn is destroyed. For more details see bitcoin #18338
ValidationInterfaceConnections& conns = g_signals.m_internals->m_connMainSignals[pwalletIn.get()];
conns.AcceptedBlockHeader = g_signals.m_internals->AcceptedBlockHeader.connect(std::bind(&CValidationInterface::AcceptedBlockHeader, pwalletIn, std::placeholders::_1));
conns.UpdatedBlockTip = g_signals.m_internals->UpdatedBlockTip.connect(std::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
conns.TransactionAddedToMempool = g_signals.m_internals->TransactionAddedToMempool.connect(std::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, std::placeholders::_1));
Expand All @@ -108,6 +109,12 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn)
conns.BlockChecked = g_signals.m_internals->BlockChecked.connect(std::bind(&CValidationInterface::BlockChecked, pwalletIn, std::placeholders::_1, std::placeholders::_2));
conns.NotifyMasternodeListChanged = g_signals.m_internals->NotifyMasternodeListChanged.connect(std::bind(&CValidationInterface::NotifyMasternodeListChanged, pwalletIn, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
}
void RegisterValidationInterface(CValidationInterface* pwalletIn)
{
// Create a shared_ptr with a no-op deleter - CValidationInterface lifecycle
// is managed by the caller.
RegisterSharedValidationInterface({pwalletIn, [](CValidationInterface*) {}});
}

void UnregisterValidationInterface(CValidationInterface* pwalletIn)
{
Expand All @@ -116,6 +123,11 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn)
}
}

void UnregisterSharedValidationInterface(std::shared_ptr<CValidationInterface> pwalletIn)
{
UnregisterValidationInterface(pwalletIn.get());
}

void UnregisterAllValidationInterfaces()
{
if (!g_signals.m_internals) {
Expand Down
12 changes: 10 additions & 2 deletions src/validationinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn);
void UnregisterValidationInterface(CValidationInterface* pwalletIn);
/** Unregister all wallets from core */
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.
void RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface> pwalletIn);
void UnregisterSharedValidationInterface(std::shared_ptr<CValidationInterface> pwalletIn);

/**
* Pushes a function to callback onto the notification queue, guaranteeing any
* callbacks generated prior to now are finished when the function is called.
Expand Down Expand Up @@ -147,7 +155,7 @@ class CValidationInterface {
/** Tells listeners to broadcast their data. */
virtual void ResendWalletTransactions(CConnman* connman) {}
virtual void BlockChecked(const CBlock&, const CValidationState&) {}
friend void ::RegisterValidationInterface(CValidationInterface*);
friend void ::RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface>);
friend void ::UnregisterValidationInterface(CValidationInterface*);
friend void ::UnregisterAllValidationInterfaces();
/** Notifies listeners of updated deterministic masternode list */
Expand All @@ -159,7 +167,7 @@ class CMainSignals {
private:
std::unique_ptr<MainSignalsInstance> m_internals;

friend void ::RegisterValidationInterface(CValidationInterface*);
friend void ::RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface>);
friend void ::UnregisterValidationInterface(CValidationInterface*);
friend void ::UnregisterAllValidationInterfaces();
friend void ::CallFunctionInValidationInterfaceQueue(std::function<void ()> func);
Expand Down

0 comments on commit b01c3df

Please sign in to comment.