diff options
author | Daniel Kraft <d@domob.eu> | 2020-09-01 09:40:43 +0200 |
---|---|---|
committer | Daniel Kraft <d@domob.eu> | 2020-09-07 10:55:54 +0200 |
commit | b93b9d54569145bfcec6cee10968284fe05fe254 (patch) | |
tree | 189c310dc208a2b6ab3bd633f0a396c3f733b797 /src | |
parent | e15b1cfc310df739b92bd281112dbeb31d3bb30a (diff) |
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')
-rw-r--r-- | src/zmq/zmqnotificationinterface.cpp | 50 |
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) |