17
17
18
18
#include < boost/signals2/signal.hpp>
19
19
20
+ struct ValidationInterfaceConnections {
21
+ boost::signals2::scoped_connection UpdatedBlockTip;
22
+ boost::signals2::scoped_connection TransactionAddedToMempool;
23
+ boost::signals2::scoped_connection BlockConnected;
24
+ boost::signals2::scoped_connection BlockDisconnected;
25
+ boost::signals2::scoped_connection TransactionRemovedFromMempool;
26
+ boost::signals2::scoped_connection ChainStateFlushed;
27
+ boost::signals2::scoped_connection Broadcast;
28
+ boost::signals2::scoped_connection BlockChecked;
29
+ boost::signals2::scoped_connection NewPoWValidBlock;
30
+ };
31
+
20
32
struct MainSignalsInstance {
21
33
boost::signals2::signal<void (const CBlockIndex *, const CBlockIndex *, bool fInitialDownload )> UpdatedBlockTip;
22
34
boost::signals2::signal<void (const CTransactionRef &)> TransactionAddedToMempool;
@@ -32,12 +44,18 @@ struct MainSignalsInstance {
32
44
// but must ensure all callbacks happen in-order, so we end up creating
33
45
// our own queue here :(
34
46
SingleThreadedSchedulerClient m_schedulerClient;
47
+ std::unordered_map<CValidationInterface*, ValidationInterfaceConnections> m_connMainSignals;
35
48
36
49
explicit MainSignalsInstance (CScheduler *pscheduler) : m_schedulerClient(pscheduler) {}
37
50
};
38
51
39
52
static CMainSignals g_signals;
40
53
54
+ // This map has to a separate global instead of a member of MainSignalsInstance,
55
+ // because RegisterWithMempoolSignals is currently called before RegisterBackgroundSignalScheduler,
56
+ // so MainSignalsInstance hasn't been created yet.
57
+ static std::unordered_map<CTxMemPool*, boost::signals2::scoped_connection> g_connNotifyEntryRemoved;
58
+
41
59
void CMainSignals::RegisterBackgroundSignalScheduler (CScheduler& scheduler) {
42
60
assert (!m_internals);
43
61
m_internals.reset (new MainSignalsInstance (&scheduler));
@@ -59,11 +77,11 @@ size_t CMainSignals::CallbacksPending() {
59
77
}
60
78
61
79
void CMainSignals::RegisterWithMempoolSignals (CTxMemPool& pool) {
62
- pool.NotifyEntryRemoved .connect (boost::bind (&CMainSignals::MempoolEntryRemoved, this , _1, _2));
80
+ g_connNotifyEntryRemoved. emplace (& pool, pool .NotifyEntryRemoved .connect (boost::bind (&CMainSignals::MempoolEntryRemoved, this , _1, _2) ));
63
81
}
64
82
65
83
void CMainSignals::UnregisterWithMempoolSignals (CTxMemPool& pool) {
66
- pool. NotifyEntryRemoved . disconnect ( boost::bind (&CMainSignals::MempoolEntryRemoved, this , _1, _2) );
84
+ g_connNotifyEntryRemoved. erase (&pool );
67
85
}
68
86
69
87
CMainSignals& GetMainSignals ()
@@ -72,42 +90,27 @@ CMainSignals& GetMainSignals()
72
90
}
73
91
74
92
void RegisterValidationInterface (CValidationInterface* pwalletIn) {
75
- g_signals.m_internals ->UpdatedBlockTip .connect (boost::bind (&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3));
76
- g_signals.m_internals ->TransactionAddedToMempool .connect (boost::bind (&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1));
77
- g_signals.m_internals ->BlockConnected .connect (boost::bind (&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3));
78
- g_signals.m_internals ->BlockDisconnected .connect (boost::bind (&CValidationInterface::BlockDisconnected, pwalletIn, _1));
79
- g_signals.m_internals ->TransactionRemovedFromMempool .connect (boost::bind (&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, _1));
80
- g_signals.m_internals ->ChainStateFlushed .connect (boost::bind (&CValidationInterface::ChainStateFlushed, pwalletIn, _1));
81
- g_signals.m_internals ->Broadcast .connect (boost::bind (&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2));
82
- g_signals.m_internals ->BlockChecked .connect (boost::bind (&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
83
- g_signals.m_internals ->NewPoWValidBlock .connect (boost::bind (&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2));
93
+ ValidationInterfaceConnections& conns = g_signals.m_internals ->m_connMainSignals [pwalletIn];
94
+ conns.UpdatedBlockTip = g_signals.m_internals ->UpdatedBlockTip .connect (boost::bind (&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3));
95
+ conns.TransactionAddedToMempool = g_signals.m_internals ->TransactionAddedToMempool .connect (boost::bind (&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1));
96
+ conns.BlockConnected = g_signals.m_internals ->BlockConnected .connect (boost::bind (&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3));
97
+ conns.BlockDisconnected = g_signals.m_internals ->BlockDisconnected .connect (boost::bind (&CValidationInterface::BlockDisconnected, pwalletIn, _1));
98
+ conns.TransactionRemovedFromMempool = g_signals.m_internals ->TransactionRemovedFromMempool .connect (boost::bind (&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, _1));
99
+ conns.ChainStateFlushed = g_signals.m_internals ->ChainStateFlushed .connect (boost::bind (&CValidationInterface::ChainStateFlushed, pwalletIn, _1));
100
+ conns.Broadcast = g_signals.m_internals ->Broadcast .connect (boost::bind (&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2));
101
+ conns.BlockChecked = g_signals.m_internals ->BlockChecked .connect (boost::bind (&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
102
+ conns.NewPoWValidBlock = g_signals.m_internals ->NewPoWValidBlock .connect (boost::bind (&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2));
84
103
}
85
104
86
105
void UnregisterValidationInterface (CValidationInterface* pwalletIn) {
87
- g_signals.m_internals ->BlockChecked .disconnect (boost::bind (&CValidationInterface::BlockChecked, pwalletIn, _1, _2));
88
- g_signals.m_internals ->Broadcast .disconnect (boost::bind (&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2));
89
- g_signals.m_internals ->ChainStateFlushed .disconnect (boost::bind (&CValidationInterface::ChainStateFlushed, pwalletIn, _1));
90
- g_signals.m_internals ->TransactionAddedToMempool .disconnect (boost::bind (&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1));
91
- g_signals.m_internals ->BlockConnected .disconnect (boost::bind (&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3));
92
- g_signals.m_internals ->BlockDisconnected .disconnect (boost::bind (&CValidationInterface::BlockDisconnected, pwalletIn, _1));
93
- g_signals.m_internals ->TransactionRemovedFromMempool .disconnect (boost::bind (&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, _1));
94
- g_signals.m_internals ->UpdatedBlockTip .disconnect (boost::bind (&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3));
95
- g_signals.m_internals ->NewPoWValidBlock .disconnect (boost::bind (&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2));
106
+ g_signals.m_internals ->m_connMainSignals .erase (pwalletIn);
96
107
}
97
108
98
109
void UnregisterAllValidationInterfaces () {
99
110
if (!g_signals.m_internals ) {
100
111
return ;
101
112
}
102
- g_signals.m_internals ->BlockChecked .disconnect_all_slots ();
103
- g_signals.m_internals ->Broadcast .disconnect_all_slots ();
104
- g_signals.m_internals ->ChainStateFlushed .disconnect_all_slots ();
105
- g_signals.m_internals ->TransactionAddedToMempool .disconnect_all_slots ();
106
- g_signals.m_internals ->BlockConnected .disconnect_all_slots ();
107
- g_signals.m_internals ->BlockDisconnected .disconnect_all_slots ();
108
- g_signals.m_internals ->TransactionRemovedFromMempool .disconnect_all_slots ();
109
- g_signals.m_internals ->UpdatedBlockTip .disconnect_all_slots ();
110
- g_signals.m_internals ->NewPoWValidBlock .disconnect_all_slots ();
113
+ g_signals.m_internals ->m_connMainSignals .clear ();
111
114
}
112
115
113
116
void CallFunctionInValidationInterfaceQueue (std::function<void ()> func) {
0 commit comments