aboutsummaryrefslogtreecommitdiff
path: root/src/zmq
diff options
context:
space:
mode:
authorDaniel Kraft <d@domob.eu>2020-09-01 09:40:43 +0200
committerDaniel Kraft <d@domob.eu>2020-09-07 10:55:54 +0200
commitb93b9d54569145bfcec6cee10968284fe05fe254 (patch)
tree189c310dc208a2b6ab3bd633f0a396c3f733b797 /src/zmq
parente15b1cfc310df739b92bd281112dbeb31d3bb30a (diff)
downloadbitcoin-b93b9d54569145bfcec6cee10968284fe05fe254.tar.xz
Simplify and fix notifier removal on error.
This factors out the common logic to run over all ZMQ notifiers, call a function on them, and remove them from the list if the function fails is extracted to a helper method. Note that this also fixes a potential memory leak: When a notifier was removed previously after its callback returned false, it would just be removed from the list without destructing the object. This is now done correctly by std::unique_ptr behind the scenes.
Diffstat (limited to 'src/zmq')
-rw-r--r--src/zmq/zmqnotificationinterface.cpp50
1 files changed, 24 insertions, 26 deletions
diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp
index 96e5b3c039..449651e65f 100644
--- a/src/zmq/zmqnotificationinterface.cpp
+++ b/src/zmq/zmqnotificationinterface.cpp
@@ -114,45 +114,43 @@ void CZMQNotificationInterface::Shutdown()
}
}
-void CZMQNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
-{
- if (fInitialDownload || pindexNew == pindexFork) // In IBD or blocks were disconnected without any new ones
- return;
+namespace {
- for (auto i = notifiers.begin(); i!=notifiers.end(); )
- {
- CZMQAbstractNotifier *notifier = i->get();
- if (notifier->NotifyBlock(pindexNew))
- {
- i++;
- }
- else
- {
+template <typename Function>
+void TryForEachAndRemoveFailed(std::list<std::unique_ptr<CZMQAbstractNotifier>>& notifiers, const Function& func)
+{
+ for (auto i = notifiers.begin(); i != notifiers.end(); ) {
+ CZMQAbstractNotifier* notifier = i->get();
+ if (func(notifier)) {
+ ++i;
+ } else {
notifier->Shutdown();
i = notifiers.erase(i);
}
}
}
+} // anonymous namespace
+
+void CZMQNotificationInterface::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
+{
+ if (fInitialDownload || pindexNew == pindexFork) // In IBD or blocks were disconnected without any new ones
+ return;
+
+ TryForEachAndRemoveFailed(notifiers, [pindexNew](CZMQAbstractNotifier* notifier) {
+ return notifier->NotifyBlock(pindexNew);
+ });
+}
+
void CZMQNotificationInterface::TransactionAddedToMempool(const CTransactionRef& ptx)
{
// Used by BlockConnected and BlockDisconnected as well, because they're
// all the same external callback.
const CTransaction& tx = *ptx;
- for (auto i = notifiers.begin(); i!=notifiers.end(); )
- {
- CZMQAbstractNotifier *notifier = i->get();
- if (notifier->NotifyTransaction(tx))
- {
- i++;
- }
- else
- {
- notifier->Shutdown();
- i = notifiers.erase(i);
- }
- }
+ TryForEachAndRemoveFailed(notifiers, [&tx](CZMQAbstractNotifier* notifier) {
+ return notifier->NotifyTransaction(tx);
+ });
}
void CZMQNotificationInterface::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected)