diff options
| author | Wladimir J. van der Laan <[email protected]> | 2017-07-11 09:30:36 +0200 |
|---|---|---|
| committer | Wladimir J. van der Laan <[email protected]> | 2017-07-11 09:38:51 +0200 |
| commit | 21ed30a314cf2118bd4719c6a09985f69fd25dbf (patch) | |
| tree | 71266d8ba79005cb0d515cd3787ca7552a5bba04 /src/validationinterface.cpp | |
| parent | Merge #10747: [rpc] fix verbose argument for getblock in bitcoin-cli (diff) | |
| parent | Expose if CScheduler is being serviced, assert its not in EmptyQueue (diff) | |
| download | discoin-21ed30a314cf2118bd4719c6a09985f69fd25dbf.tar.xz discoin-21ed30a314cf2118bd4719c6a09985f69fd25dbf.zip | |
Merge #10179: Give CValidationInterface Support for calling notifications on the CScheduler Thread
1f668b6 Expose if CScheduler is being serviced, assert its not in EmptyQueue (Matt Corallo)
3192975 Flush CValidationInterface callbacks prior to destruction (Matt Corallo)
08096bb Support more than one CScheduler thread for serial clients (Matt Corallo)
2fbf2db Add default arg to CScheduler to schedule() a callback now (Matt Corallo)
cda1429 Give CMainSignals a reference to the global scheduler (Matt Corallo)
3a19fed Make ValidationInterface signals-type-agnostic (Matt Corallo)
ff6a834 Use TestingSetup to DRY qt rpcnestedtests (Matt Corallo)
Tree-SHA512: fab91e34e30b080ed4d0a6d8c1214910e383c45440676e37be61d0bde6ae98d61e8903d22b846e95ba4e73a6ce788798350266feba246d8a2ab357e8523e4ac5
Diffstat (limited to 'src/validationinterface.cpp')
| -rw-r--r-- | src/validationinterface.cpp | 131 |
1 files changed, 104 insertions, 27 deletions
diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index be2f20b86..bf20d606f 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -4,46 +4,123 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "validationinterface.h" +#include "init.h" +#include "scheduler.h" +#include "sync.h" +#include "util.h" + +#include <list> +#include <atomic> + +#include <boost/signals2/signal.hpp> + +struct MainSignalsInstance { + boost::signals2::signal<void (const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)> UpdatedBlockTip; + boost::signals2::signal<void (const CTransactionRef &)> TransactionAddedToMempool; + boost::signals2::signal<void (const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::vector<CTransactionRef>&)> BlockConnected; + boost::signals2::signal<void (const std::shared_ptr<const CBlock> &)> BlockDisconnected; + boost::signals2::signal<void (const CBlockLocator &)> SetBestChain; + boost::signals2::signal<void (const uint256 &)> Inventory; + boost::signals2::signal<void (int64_t nBestBlockTime, CConnman* connman)> Broadcast; + boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked; + boost::signals2::signal<void (const CBlockIndex *, const std::shared_ptr<const CBlock>&)> NewPoWValidBlock; + + // We are not allowed to assume the scheduler only runs in one thread, + // but must ensure all callbacks happen in-order, so we end up creating + // our own queue here :( + SingleThreadedSchedulerClient m_schedulerClient; + + MainSignalsInstance(CScheduler *pscheduler) : m_schedulerClient(pscheduler) {} +}; static CMainSignals g_signals; +void CMainSignals::RegisterBackgroundSignalScheduler(CScheduler& scheduler) { + assert(!m_internals); + m_internals.reset(new MainSignalsInstance(&scheduler)); +} + +void CMainSignals::UnregisterBackgroundSignalScheduler() { + m_internals.reset(nullptr); +} + +void CMainSignals::FlushBackgroundCallbacks() { + m_internals->m_schedulerClient.EmptyQueue(); +} + CMainSignals& GetMainSignals() { return g_signals; } void RegisterValidationInterface(CValidationInterface* pwalletIn) { - g_signals.UpdatedBlockTip.connect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3)); - g_signals.TransactionAddedToMempool.connect(boost::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1)); - g_signals.BlockConnected.connect(boost::bind(&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3)); - g_signals.BlockDisconnected.connect(boost::bind(&CValidationInterface::BlockDisconnected, pwalletIn, _1)); - g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); - g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); - g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2)); - g_signals.BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); - g_signals.NewPoWValidBlock.connect(boost::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2)); + g_signals.m_internals->UpdatedBlockTip.connect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3)); + g_signals.m_internals->TransactionAddedToMempool.connect(boost::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1)); + g_signals.m_internals->BlockConnected.connect(boost::bind(&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3)); + g_signals.m_internals->BlockDisconnected.connect(boost::bind(&CValidationInterface::BlockDisconnected, pwalletIn, _1)); + g_signals.m_internals->SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); + g_signals.m_internals->Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); + g_signals.m_internals->Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2)); + g_signals.m_internals->BlockChecked.connect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); + g_signals.m_internals->NewPoWValidBlock.connect(boost::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2)); } void UnregisterValidationInterface(CValidationInterface* pwalletIn) { - g_signals.BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); - g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2)); - g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); - g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); - g_signals.TransactionAddedToMempool.disconnect(boost::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1)); - g_signals.BlockConnected.disconnect(boost::bind(&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3)); - g_signals.BlockDisconnected.disconnect(boost::bind(&CValidationInterface::BlockDisconnected, pwalletIn, _1)); - g_signals.UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3)); - g_signals.NewPoWValidBlock.disconnect(boost::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2)); + g_signals.m_internals->BlockChecked.disconnect(boost::bind(&CValidationInterface::BlockChecked, pwalletIn, _1, _2)); + g_signals.m_internals->Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2)); + g_signals.m_internals->Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1)); + g_signals.m_internals->SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1)); + g_signals.m_internals->TransactionAddedToMempool.disconnect(boost::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1)); + g_signals.m_internals->BlockConnected.disconnect(boost::bind(&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3)); + g_signals.m_internals->BlockDisconnected.disconnect(boost::bind(&CValidationInterface::BlockDisconnected, pwalletIn, _1)); + g_signals.m_internals->UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3)); + g_signals.m_internals->NewPoWValidBlock.disconnect(boost::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2)); } void UnregisterAllValidationInterfaces() { - g_signals.BlockChecked.disconnect_all_slots(); - g_signals.Broadcast.disconnect_all_slots(); - g_signals.Inventory.disconnect_all_slots(); - g_signals.SetBestChain.disconnect_all_slots(); - g_signals.TransactionAddedToMempool.disconnect_all_slots(); - g_signals.BlockConnected.disconnect_all_slots(); - g_signals.BlockDisconnected.disconnect_all_slots(); - g_signals.UpdatedBlockTip.disconnect_all_slots(); - g_signals.NewPoWValidBlock.disconnect_all_slots(); + g_signals.m_internals->BlockChecked.disconnect_all_slots(); + g_signals.m_internals->Broadcast.disconnect_all_slots(); + g_signals.m_internals->Inventory.disconnect_all_slots(); + g_signals.m_internals->SetBestChain.disconnect_all_slots(); + g_signals.m_internals->TransactionAddedToMempool.disconnect_all_slots(); + g_signals.m_internals->BlockConnected.disconnect_all_slots(); + g_signals.m_internals->BlockDisconnected.disconnect_all_slots(); + g_signals.m_internals->UpdatedBlockTip.disconnect_all_slots(); + g_signals.m_internals->NewPoWValidBlock.disconnect_all_slots(); +} + +void CMainSignals::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) { + m_internals->UpdatedBlockTip(pindexNew, pindexFork, fInitialDownload); +} + +void CMainSignals::TransactionAddedToMempool(const CTransactionRef &ptx) { + m_internals->TransactionAddedToMempool(ptx); +} + +void CMainSignals::BlockConnected(const std::shared_ptr<const CBlock> &pblock, const CBlockIndex *pindex, const std::vector<CTransactionRef>& vtxConflicted) { + m_internals->BlockConnected(pblock, pindex, vtxConflicted); +} + +void CMainSignals::BlockDisconnected(const std::shared_ptr<const CBlock> &pblock) { + m_internals->BlockDisconnected(pblock); +} + +void CMainSignals::SetBestChain(const CBlockLocator &locator) { + m_internals->SetBestChain(locator); +} + +void CMainSignals::Inventory(const uint256 &hash) { + m_internals->Inventory(hash); +} + +void CMainSignals::Broadcast(int64_t nBestBlockTime, CConnman* connman) { + m_internals->Broadcast(nBestBlockTime, connman); +} + +void CMainSignals::BlockChecked(const CBlock& block, const CValidationState& state) { + m_internals->BlockChecked(block, state); +} + +void CMainSignals::NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock> &block) { + m_internals->NewPoWValidBlock(pindex, block); } |