/bitcoin/src/util/btcsignals.h
Line | Count | Source |
1 | | // Copyright (c) The Bitcoin Core developers |
2 | | // Distributed under the MIT software license, see the accompanying |
3 | | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
4 | | |
5 | | #ifndef BITCOIN_UTIL_BTCSIGNALS_H |
6 | | #define BITCOIN_UTIL_BTCSIGNALS_H |
7 | | |
8 | | #include <sync.h> |
9 | | |
10 | | #include <algorithm> |
11 | | #include <atomic> |
12 | | #include <functional> |
13 | | #include <memory> |
14 | | #include <optional> |
15 | | #include <type_traits> |
16 | | #include <utility> |
17 | | #include <vector> |
18 | | |
19 | | /** |
20 | | * btcsignals is a simple mechanism for signaling events to multiple subscribers. |
21 | | * It is api-compatible with a minimal subset of boost::signals2. |
22 | | * |
23 | | * Rather than using a custom slot type, and the features/complexity that they |
24 | | * imply, std::function is used to store the callbacks. Lifetime management of |
25 | | * the callbacks is left up to the user. |
26 | | * |
27 | | * All usage is thread-safe except for interacting with a connection while |
28 | | * copying/moving it on another thread. |
29 | | */ |
30 | | |
31 | | namespace btcsignals { |
32 | | |
33 | | /// The default combiner, which only returns void. |
34 | | class null_value |
35 | | { |
36 | | public: |
37 | | using result_type = void; |
38 | | }; |
39 | | |
40 | | /// A combiner, which checks if at least one callback returned true. |
41 | | class any_of |
42 | | { |
43 | | public: |
44 | | // This is the only supported combiner with a non-void return type. As |
45 | | // such, its behavior is embedded into the signal functor. |
46 | | using result_type = bool; |
47 | | }; |
48 | | |
49 | | template <typename Signature, typename Combiner = null_value> |
50 | | class signal; |
51 | | |
52 | | /* |
53 | | * State object representing the liveness of a registered callback. |
54 | | * signal::connect() returns an enabled connection which can be held and |
55 | | * disabled in the future. |
56 | | */ |
57 | | class connection |
58 | | { |
59 | | template <typename Signature, typename Combiner> |
60 | | friend class signal; |
61 | | /** |
62 | | * Track liveness. Also serves as a tag for the constructor used by signal. |
63 | | */ |
64 | | class liveness |
65 | | { |
66 | | friend class connection; |
67 | | std::atomic_bool m_connected{true}; |
68 | | |
69 | 0 | void disconnect() { m_connected.store(false); } |
70 | | public: |
71 | 351 | bool connected() const { return m_connected.load(); } |
72 | | }; |
73 | | |
74 | | /** |
75 | | * connections have shared_ptr-like copy and move semantics. |
76 | | */ |
77 | | std::shared_ptr<liveness> m_state{}; |
78 | | |
79 | | /** |
80 | | * Only a signal can create an enabled connection. |
81 | | */ |
82 | 108 | explicit connection(std::shared_ptr<liveness>&& state) : m_state{std::move(state)}{} |
83 | | |
84 | | public: |
85 | | /** |
86 | | * The default constructor creates a connection with no associated signal |
87 | | */ |
88 | | constexpr connection() noexcept = default; |
89 | | |
90 | | /** |
91 | | * If a callback is associated with this connection, prevent it from being |
92 | | * called in the future. |
93 | | * |
94 | | * If a connection is disabled as part of a signal's callback function, it |
95 | | * will _not_ be executed in the current signal invocation. |
96 | | * |
97 | | * Note that disconnected callbacks are not removed from their owning |
98 | | * signals here. They are garbage collected in signal::connect(). |
99 | | */ |
100 | | void disconnect() |
101 | 0 | { |
102 | 0 | if (m_state) { Branch (102:13): [True: 0, False: 0]
|
103 | 0 | m_state->disconnect(); |
104 | 0 | } |
105 | 0 | } |
106 | | |
107 | | /** |
108 | | * Returns true if this connection was created by a signal and has not been |
109 | | * disabled. |
110 | | */ |
111 | | bool connected() const |
112 | 0 | { |
113 | 0 | return m_state && m_state->connected(); |
114 | 0 | } |
115 | | }; |
116 | | |
117 | | /* |
118 | | * RAII-style connection management |
119 | | */ |
120 | | class scoped_connection |
121 | | { |
122 | | connection m_conn; |
123 | | |
124 | | public: |
125 | 0 | explicit scoped_connection(connection rhs) noexcept : m_conn{std::move(rhs)} {} |
126 | | |
127 | | scoped_connection(scoped_connection&&) noexcept = default; |
128 | | |
129 | | /** |
130 | | * For simplicity, disable copy construction and copy/move assignment. |
131 | | */ |
132 | | scoped_connection& operator=(scoped_connection&&) = delete; |
133 | | scoped_connection& operator=(const scoped_connection&) = delete; |
134 | | scoped_connection(const scoped_connection&) = delete; |
135 | | |
136 | | void disconnect() |
137 | 0 | { |
138 | 0 | m_conn.disconnect(); |
139 | 0 | } |
140 | | |
141 | | ~scoped_connection() |
142 | 0 | { |
143 | 0 | disconnect(); |
144 | 0 | } |
145 | | }; |
146 | | |
147 | | /* |
148 | | * Functor for calling zero or more connected callbacks |
149 | | */ |
150 | | template <typename Signature, typename Combiner> |
151 | | class signal |
152 | | { |
153 | | using function_type = std::function<Signature>; |
154 | | |
155 | | /* |
156 | | * Helper struct for maintaining a callback and its associated connection liveness |
157 | | */ |
158 | | struct connection_holder : connection::liveness { |
159 | | template <typename Callable> |
160 | 108 | connection_holder(Callable&& callback) : m_callback{std::forward<Callable>(callback)} |
161 | 108 | { |
162 | 108 | } btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), btcsignals::null_value>::connection_holder::connection_holder<void (&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>(void (&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)) Line | Count | Source | 160 | 54 | connection_holder(Callable&& callback) : m_callback{std::forward<Callable>(callback)} | 161 | 54 | { | 162 | 54 | } |
Unexecuted instantiation: init.cpp:btcsignals::signal<void (SynchronizationState, CBlockIndex const&, double), btcsignals::null_value>::connection_holder::connection_holder<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_9>(AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_9&&) Unexecuted instantiation: btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), btcsignals::null_value>::connection_holder::connection_holder<std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>&>(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>&) Unexecuted instantiation: btcsignals::signal<void (bilingual_str const&, unsigned int), btcsignals::null_value>::connection_holder::connection_holder<std::function<void (bilingual_str const&, unsigned int)>&>(std::function<void (bilingual_str const&, unsigned int)>&) Unexecuted instantiation: btcsignals::signal<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int), btcsignals::any_of>::connection_holder::connection_holder<std::function<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)>&>(std::function<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)>&) Unexecuted instantiation: btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool), btcsignals::null_value>::connection_holder::connection_holder<std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool)>&>(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool)>&) Unexecuted instantiation: btcsignals::signal<void (), btcsignals::null_value>::connection_holder::connection_holder<std::function<void ()>&>(std::function<void ()>&) Unexecuted instantiation: btcsignals::signal<void (int), btcsignals::null_value>::connection_holder::connection_holder<std::function<void (int)>&>(std::function<void (int)>&) Unexecuted instantiation: btcsignals::signal<void (bool), btcsignals::null_value>::connection_holder::connection_holder<std::function<void (bool)>&>(std::function<void (bool)>&) Unexecuted instantiation: interfaces.cpp:btcsignals::signal<void (SynchronizationState, CBlockIndex const&, double), btcsignals::null_value>::connection_holder::connection_holder<node::(anonymous namespace)::NodeImpl::handleNotifyBlockTip(std::function<void (SynchronizationState, interfaces::BlockTip, double)>)::{lambda(SynchronizationState, CBlockIndex const&, double)#1}>(node::(anonymous namespace)::NodeImpl::handleNotifyBlockTip(std::function<void (SynchronizationState, interfaces::BlockTip, double)>)::{lambda(SynchronizationState, CBlockIndex const&, double)#1}&&)Unexecuted instantiation: interfaces.cpp:btcsignals::signal<void (SynchronizationState, long, long, bool), btcsignals::null_value>::connection_holder::connection_holder<node::(anonymous namespace)::NodeImpl::handleNotifyHeaderTip(std::function<void (SynchronizationState, interfaces::BlockTip, bool)>)::{lambda(SynchronizationState, long, long, bool)#1}>(node::(anonymous namespace)::NodeImpl::handleNotifyHeaderTip(std::function<void (SynchronizationState, interfaces::BlockTip, bool)>)::{lambda(SynchronizationState, long, long, bool)#1}&&)btcsignals::signal<void (bilingual_str const&, unsigned int), btcsignals::null_value>::connection_holder::connection_holder<void (&)(bilingual_str const&, unsigned int)>(void (&)(bilingual_str const&, unsigned int)) Line | Count | Source | 160 | 27 | connection_holder(Callable&& callback) : m_callback{std::forward<Callable>(callback)} | 161 | 27 | { | 162 | 27 | } |
btcsignals::signal<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int), btcsignals::any_of>::connection_holder::connection_holder<bool (&)(bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)>(bool (&)(bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)) Line | Count | Source | 160 | 27 | connection_holder(Callable&& callback) : m_callback{std::forward<Callable>(callback)} | 161 | 27 | { | 162 | 27 | } |
Unexecuted instantiation: btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int), btcsignals::null_value>::connection_holder::connection_holder<std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)>&>(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)>&) Unexecuted instantiation: interfaces.cpp:btcsignals::signal<void (wallet::CWallet*), btcsignals::null_value>::connection_holder::connection_holder<wallet::(anonymous namespace)::WalletImpl::handleStatusChanged(std::function<void ()>)::{lambda(wallet::CWallet*)#1}>(wallet::(anonymous namespace)::WalletImpl::handleStatusChanged(std::function<void ()>)::{lambda(wallet::CWallet*)#1}&&)Unexecuted instantiation: interfaces.cpp:btcsignals::signal<void (std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType), btcsignals::null_value>::connection_holder::connection_holder<wallet::(anonymous namespace)::WalletImpl::handleAddressBookChanged(std::function<void (std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType)>)::{lambda(std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType)#1}>(wallet::(anonymous namespace)::WalletImpl::handleAddressBookChanged(std::function<void (std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType)>)::{lambda(std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType)#1}&&)Unexecuted instantiation: interfaces.cpp:btcsignals::signal<void (transaction_identifier<false> const&, ChangeType), btcsignals::null_value>::connection_holder::connection_holder<wallet::(anonymous namespace)::WalletImpl::handleTransactionChanged(std::function<void (transaction_identifier<false> const&, ChangeType)>)::{lambda(transaction_identifier<false> const&, ChangeType)#1}>(wallet::(anonymous namespace)::WalletImpl::handleTransactionChanged(std::function<void (transaction_identifier<false> const&, ChangeType)>)::{lambda(transaction_identifier<false> const&, ChangeType)#1}&&)Unexecuted instantiation: wallet.cpp:btcsignals::signal<void (), btcsignals::null_value>::connection_holder::connection_holder<wallet::CWallet::ConnectScriptPubKeyManNotifiers()::$_0>(wallet::CWallet::ConnectScriptPubKeyManNotifiers()::$_0&&) Unexecuted instantiation: wallet.cpp:btcsignals::signal<void (wallet::ScriptPubKeyMan const*, long), btcsignals::null_value>::connection_holder::connection_holder<wallet::CWallet::ConnectScriptPubKeyManNotifiers()::$_1>(wallet::CWallet::ConnectScriptPubKeyManNotifiers()::$_1&&) |
163 | | |
164 | | const function_type m_callback; |
165 | | }; |
166 | | |
167 | | mutable Mutex m_mutex; |
168 | | |
169 | | std::vector<std::shared_ptr<connection_holder>> m_connections GUARDED_BY(m_mutex){}; |
170 | | |
171 | | public: |
172 | | using result_type = Combiner::result_type; |
173 | | |
174 | 0 | constexpr signal() noexcept = default; Unexecuted instantiation: btcsignals::signal<void (), btcsignals::null_value>::signal() Unexecuted instantiation: btcsignals::signal<void (wallet::ScriptPubKeyMan const*, long), btcsignals::null_value>::signal() Unexecuted instantiation: btcsignals::signal<void (std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType), btcsignals::null_value>::signal() Unexecuted instantiation: btcsignals::signal<void (transaction_identifier<false> const&, ChangeType), btcsignals::null_value>::signal() Unexecuted instantiation: btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int), btcsignals::null_value>::signal() Unexecuted instantiation: btcsignals::signal<void (wallet::CWallet*), btcsignals::null_value>::signal() |
175 | 3.30M | ~signal() = default; btcsignals::signal<void (), btcsignals::null_value>::~signal() Line | Count | Source | 175 | 1.50M | ~signal() = default; |
Unexecuted instantiation: btcsignals::signal<void (SynchronizationState, long, long, bool), btcsignals::null_value>::~signal() Unexecuted instantiation: btcsignals::signal<void (SynchronizationState, CBlockIndex const&, double), btcsignals::null_value>::~signal() Unexecuted instantiation: btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool), btcsignals::null_value>::~signal() Unexecuted instantiation: btcsignals::signal<void (bool), btcsignals::null_value>::~signal() Unexecuted instantiation: btcsignals::signal<void (int), btcsignals::null_value>::~signal() Unexecuted instantiation: btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), btcsignals::null_value>::~signal() Unexecuted instantiation: btcsignals::signal<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int), btcsignals::any_of>::~signal() Unexecuted instantiation: btcsignals::signal<void (bilingual_str const&, unsigned int), btcsignals::null_value>::~signal() btcsignals::signal<void (wallet::ScriptPubKeyMan const*, long), btcsignals::null_value>::~signal() Line | Count | Source | 175 | 1.20M | ~signal() = default; |
btcsignals::signal<void (wallet::CWallet*), btcsignals::null_value>::~signal() Line | Count | Source | 175 | 150k | ~signal() = default; |
btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int), btcsignals::null_value>::~signal() Line | Count | Source | 175 | 150k | ~signal() = default; |
btcsignals::signal<void (transaction_identifier<false> const&, ChangeType), btcsignals::null_value>::~signal() Line | Count | Source | 175 | 150k | ~signal() = default; |
btcsignals::signal<void (std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType), btcsignals::null_value>::~signal() Line | Count | Source | 175 | 150k | ~signal() = default; |
|
176 | | |
177 | | /* |
178 | | * For simplicity, disable all moving/copying/assigning. |
179 | | */ |
180 | | signal(const signal&) = delete; |
181 | | signal(signal&&) = delete; |
182 | | signal& operator=(const signal&) = delete; |
183 | | signal& operator=(signal&&) = delete; |
184 | | |
185 | | /* |
186 | | * Execute all enabled callbacks for the signal. Rather than allowing for |
187 | | * custom combiners, the behavior of any_of is hard-coded here. |
188 | | * |
189 | | * Callbacks which return void require special handling. |
190 | | * |
191 | | * In order to avoid locking during the callbacks, the list of callbacks is |
192 | | * cached before they are called. This allows a callback to call connect(), |
193 | | * but the newly connected callback will not be run during the current |
194 | | * signal invocation. |
195 | | * |
196 | | * Note that the parameters are accepted as universal references, though |
197 | | * they are not perfectly forwarded as that could cause a use-after-move if |
198 | | * more than one callback is enabled. |
199 | | */ |
200 | | template <typename... Args> |
201 | | [[nodiscard]] result_type operator()(Args&&... args) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex) |
202 | 271k | { |
203 | 271k | std::vector<std::shared_ptr<connection_holder>> connections; |
204 | 271k | { |
205 | 271k | LOCK(m_mutex); |
206 | 271k | connections = m_connections; |
207 | 271k | } |
208 | 271k | if constexpr (std::is_void_v<result_type>) { |
209 | 271k | static_assert(std::is_same_v<result_type, typename function_type::result_type>, |
210 | 271k | "Callback result type must be equal to the combiner result type (void)."); |
211 | 271k | for (const auto& connection : connections) { Branch (211:41): [True: 27, False: 27]
Branch (211:41): [True: 216, False: 108]
Branch (211:41): [True: 0, False: 150k]
Branch (211:41): [True: 0, False: 0]
Branch (211:41): [True: 0, False: 56.7k]
Branch (211:41): [True: 0, False: 0]
Branch (211:41): [True: 27, False: 27]
Branch (211:41): [True: 0, False: 0]
Branch (211:41): [True: 54, False: 27]
Branch (211:41): [True: 0, False: 0]
Branch (211:41): [True: 0, False: 21.8k]
Branch (211:41): [True: 0, False: 42.3k]
Branch (211:41): [True: 0, False: 0]
Branch (211:41): [True: 0, False: 0]
Branch (211:41): [True: 0, False: 0]
Branch (211:41): [True: 0, False: 0]
Branch (211:41): [True: 0, False: 0]
Branch (211:41): [True: 0, False: 0]
Branch (211:41): [True: 0, False: 0]
Branch (211:41): [True: 0, False: 0]
|
212 | 324 | if (connection->connected()) { Branch (212:21): [True: 27, False: 0]
Branch (212:21): [True: 216, False: 0]
Branch (212:21): [True: 0, False: 0]
Branch (212:21): [True: 0, False: 0]
Branch (212:21): [True: 0, False: 0]
Branch (212:21): [True: 0, False: 0]
Branch (212:21): [True: 27, False: 0]
Branch (212:21): [True: 0, False: 0]
Branch (212:21): [True: 54, False: 0]
Branch (212:21): [True: 0, False: 0]
Branch (212:21): [True: 0, False: 0]
Branch (212:21): [True: 0, False: 0]
Branch (212:21): [True: 0, False: 0]
Branch (212:21): [True: 0, False: 0]
Branch (212:21): [True: 0, False: 0]
Branch (212:21): [True: 0, False: 0]
Branch (212:21): [True: 0, False: 0]
Branch (212:21): [True: 0, False: 0]
Branch (212:21): [True: 0, False: 0]
Branch (212:21): [True: 0, False: 0]
|
213 | 324 | connection->m_callback(args...); |
214 | 324 | } |
215 | 324 | } |
216 | 271k | } else { |
217 | 0 | static_assert(std::is_same_v<Combiner, any_of>, |
218 | 0 | "only the any_of combiner is supported and hard-coded into this functor."); |
219 | 0 | static_assert(std::is_same_v<result_type, typename function_type::result_type>, |
220 | 0 | "Callback result type must be equal to the combiner result type (bool)."); |
221 | 0 | result_type ret{false}; |
222 | 0 | for (const auto& connection : connections) { Branch (222:41): [True: 0, False: 0]
|
223 | 0 | if (connection->connected()) { Branch (223:21): [True: 0, False: 0]
|
224 | 0 | ret |= connection->m_callback(args...); |
225 | 0 | } |
226 | 0 | } |
227 | 0 | return ret; |
228 | 0 | } |
229 | 271k | } void btcsignals::signal<void (bilingual_str const&, unsigned int), btcsignals::null_value>::operator()<util::TranslatedLiteral, CClientUIInterface::MessageBoxFlags>(util::TranslatedLiteral&&, CClientUIInterface::MessageBoxFlags&&) const Line | Count | Source | 202 | 27 | { | 203 | 27 | std::vector<std::shared_ptr<connection_holder>> connections; | 204 | 27 | { | 205 | 27 | LOCK(m_mutex); | 206 | 27 | connections = m_connections; | 207 | 27 | } | 208 | 27 | if constexpr (std::is_void_v<result_type>) { | 209 | 27 | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 210 | 27 | "Callback result type must be equal to the combiner result type (void)."); | 211 | 27 | for (const auto& connection : connections) { Branch (211:41): [True: 27, False: 27]
| 212 | 27 | if (connection->connected()) { Branch (212:21): [True: 27, False: 0]
| 213 | 27 | connection->m_callback(args...); | 214 | 27 | } | 215 | 27 | } | 216 | | } else { | 217 | | static_assert(std::is_same_v<Combiner, any_of>, | 218 | | "only the any_of combiner is supported and hard-coded into this functor."); | 219 | | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 220 | | "Callback result type must be equal to the combiner result type (bool)."); | 221 | | result_type ret{false}; | 222 | | for (const auto& connection : connections) { | 223 | | if (connection->connected()) { | 224 | | ret |= connection->m_callback(args...); | 225 | | } | 226 | | } | 227 | | return ret; | 228 | | } | 229 | 27 | } |
void btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), btcsignals::null_value>::operator()<util::TranslatedLiteral>(util::TranslatedLiteral&&) const Line | Count | Source | 202 | 108 | { | 203 | 108 | std::vector<std::shared_ptr<connection_holder>> connections; | 204 | 108 | { | 205 | 108 | LOCK(m_mutex); | 206 | 108 | connections = m_connections; | 207 | 108 | } | 208 | 108 | if constexpr (std::is_void_v<result_type>) { | 209 | 108 | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 210 | 108 | "Callback result type must be equal to the combiner result type (void)."); | 211 | 216 | for (const auto& connection : connections) { Branch (211:41): [True: 216, False: 108]
| 212 | 216 | if (connection->connected()) { Branch (212:21): [True: 216, False: 0]
| 213 | 216 | connection->m_callback(args...); | 214 | 216 | } | 215 | 216 | } | 216 | | } else { | 217 | | static_assert(std::is_same_v<Combiner, any_of>, | 218 | | "only the any_of combiner is supported and hard-coded into this functor."); | 219 | | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 220 | | "Callback result type must be equal to the combiner result type (bool)."); | 221 | | result_type ret{false}; | 222 | | for (const auto& connection : connections) { | 223 | | if (connection->connected()) { | 224 | | ret |= connection->m_callback(args...); | 225 | | } | 226 | | } | 227 | | return ret; | 228 | | } | 229 | 108 | } |
void btcsignals::signal<void (), btcsignals::null_value>::operator()<>() const Line | Count | Source | 202 | 150k | { | 203 | 150k | std::vector<std::shared_ptr<connection_holder>> connections; | 204 | 150k | { | 205 | 150k | LOCK(m_mutex); | 206 | 150k | connections = m_connections; | 207 | 150k | } | 208 | 150k | if constexpr (std::is_void_v<result_type>) { | 209 | 150k | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 210 | 150k | "Callback result type must be equal to the combiner result type (void)."); | 211 | 150k | for (const auto& connection : connections) { Branch (211:41): [True: 0, False: 150k]
| 212 | 0 | if (connection->connected()) { Branch (212:21): [True: 0, False: 0]
| 213 | 0 | connection->m_callback(args...); | 214 | 0 | } | 215 | 0 | } | 216 | | } else { | 217 | | static_assert(std::is_same_v<Combiner, any_of>, | 218 | | "only the any_of combiner is supported and hard-coded into this functor."); | 219 | | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 220 | | "Callback result type must be equal to the combiner result type (bool)."); | 221 | | result_type ret{false}; | 222 | | for (const auto& connection : connections) { | 223 | | if (connection->connected()) { | 224 | | ret |= connection->m_callback(args...); | 225 | | } | 226 | | } | 227 | | return ret; | 228 | | } | 229 | 150k | } |
Unexecuted instantiation: bool btcsignals::signal<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int), btcsignals::any_of>::operator()<bilingual_str, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int>(bilingual_str&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, unsigned int&&) const Unexecuted instantiation: void btcsignals::signal<void (bilingual_str const&, unsigned int), btcsignals::null_value>::operator()<bilingual_str, CClientUIInterface::MessageBoxFlags>(bilingual_str&&, CClientUIInterface::MessageBoxFlags&&) const void btcsignals::signal<void (int), btcsignals::null_value>::operator()<unsigned long&>(unsigned long&) const Line | Count | Source | 202 | 56.7k | { | 203 | 56.7k | std::vector<std::shared_ptr<connection_holder>> connections; | 204 | 56.7k | { | 205 | 56.7k | LOCK(m_mutex); | 206 | 56.7k | connections = m_connections; | 207 | 56.7k | } | 208 | 56.7k | if constexpr (std::is_void_v<result_type>) { | 209 | 56.7k | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 210 | 56.7k | "Callback result type must be equal to the combiner result type (void)."); | 211 | 56.7k | for (const auto& connection : connections) { Branch (211:41): [True: 0, False: 56.7k]
| 212 | 0 | if (connection->connected()) { Branch (212:21): [True: 0, False: 0]
| 213 | 0 | connection->m_callback(args...); | 214 | 0 | } | 215 | 0 | } | 216 | | } else { | 217 | | static_assert(std::is_same_v<Combiner, any_of>, | 218 | | "only the any_of combiner is supported and hard-coded into this functor."); | 219 | | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 220 | | "Callback result type must be equal to the combiner result type (bool)."); | 221 | | result_type ret{false}; | 222 | | for (const auto& connection : connections) { | 223 | | if (connection->connected()) { | 224 | | ret |= connection->m_callback(args...); | 225 | | } | 226 | | } | 227 | | return ret; | 228 | | } | 229 | 56.7k | } |
Unexecuted instantiation: void btcsignals::signal<void (bool), btcsignals::null_value>::operator()<std::atomic<bool>&>(std::atomic<bool>&) const void btcsignals::signal<void (bilingual_str const&, unsigned int), btcsignals::null_value>::operator()<bilingual_str&, CClientUIInterface::MessageBoxFlags>(bilingual_str&, CClientUIInterface::MessageBoxFlags&&) const Line | Count | Source | 202 | 27 | { | 203 | 27 | std::vector<std::shared_ptr<connection_holder>> connections; | 204 | 27 | { | 205 | 27 | LOCK(m_mutex); | 206 | 27 | connections = m_connections; | 207 | 27 | } | 208 | 27 | if constexpr (std::is_void_v<result_type>) { | 209 | 27 | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 210 | 27 | "Callback result type must be equal to the combiner result type (void)."); | 211 | 27 | for (const auto& connection : connections) { Branch (211:41): [True: 27, False: 27]
| 212 | 27 | if (connection->connected()) { Branch (212:21): [True: 27, False: 0]
| 213 | 27 | connection->m_callback(args...); | 214 | 27 | } | 215 | 27 | } | 216 | | } else { | 217 | | static_assert(std::is_same_v<Combiner, any_of>, | 218 | | "only the any_of combiner is supported and hard-coded into this functor."); | 219 | | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 220 | | "Callback result type must be equal to the combiner result type (bool)."); | 221 | | result_type ret{false}; | 222 | | for (const auto& connection : connections) { | 223 | | if (connection->connected()) { | 224 | | ret |= connection->m_callback(args...); | 225 | | } | 226 | | } | 227 | | return ret; | 228 | | } | 229 | 27 | } |
Unexecuted instantiation: void btcsignals::signal<void (bilingual_str const&, unsigned int), btcsignals::null_value>::operator()<bilingual_str const&, CClientUIInterface::MessageBoxFlags>(bilingual_str const&, CClientUIInterface::MessageBoxFlags&&) const void btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), btcsignals::null_value>::operator()<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const Line | Count | Source | 202 | 27 | { | 203 | 27 | std::vector<std::shared_ptr<connection_holder>> connections; | 204 | 27 | { | 205 | 27 | LOCK(m_mutex); | 206 | 27 | connections = m_connections; | 207 | 27 | } | 208 | 27 | if constexpr (std::is_void_v<result_type>) { | 209 | 27 | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 210 | 27 | "Callback result type must be equal to the combiner result type (void)."); | 211 | 54 | for (const auto& connection : connections) { Branch (211:41): [True: 54, False: 27]
| 212 | 54 | if (connection->connected()) { Branch (212:21): [True: 54, False: 0]
| 213 | 54 | connection->m_callback(args...); | 214 | 54 | } | 215 | 54 | } | 216 | | } else { | 217 | | static_assert(std::is_same_v<Combiner, any_of>, | 218 | | "only the any_of combiner is supported and hard-coded into this functor."); | 219 | | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 220 | | "Callback result type must be equal to the combiner result type (bool)."); | 221 | | result_type ret{false}; | 222 | | for (const auto& connection : connections) { | 223 | | if (connection->connected()) { | 224 | | ret |= connection->m_callback(args...); | 225 | | } | 226 | | } | 227 | | return ret; | 228 | | } | 229 | 27 | } |
Unexecuted instantiation: void btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool), btcsignals::null_value>::operator()<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int&, bool&>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int&, bool&) const void btcsignals::signal<void (SynchronizationState, CBlockIndex const&, double), btcsignals::null_value>::operator()<SynchronizationState&, CBlockIndex const&, double&>(SynchronizationState&, CBlockIndex const&, double&) const Line | Count | Source | 202 | 21.8k | { | 203 | 21.8k | std::vector<std::shared_ptr<connection_holder>> connections; | 204 | 21.8k | { | 205 | 21.8k | LOCK(m_mutex); | 206 | 21.8k | connections = m_connections; | 207 | 21.8k | } | 208 | 21.8k | if constexpr (std::is_void_v<result_type>) { | 209 | 21.8k | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 210 | 21.8k | "Callback result type must be equal to the combiner result type (void)."); | 211 | 21.8k | for (const auto& connection : connections) { Branch (211:41): [True: 0, False: 21.8k]
| 212 | 0 | if (connection->connected()) { Branch (212:21): [True: 0, False: 0]
| 213 | 0 | connection->m_callback(args...); | 214 | 0 | } | 215 | 0 | } | 216 | | } else { | 217 | | static_assert(std::is_same_v<Combiner, any_of>, | 218 | | "only the any_of combiner is supported and hard-coded into this functor."); | 219 | | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 220 | | "Callback result type must be equal to the combiner result type (bool)."); | 221 | | result_type ret{false}; | 222 | | for (const auto& connection : connections) { | 223 | | if (connection->connected()) { | 224 | | ret |= connection->m_callback(args...); | 225 | | } | 226 | | } | 227 | | return ret; | 228 | | } | 229 | 21.8k | } |
void btcsignals::signal<void (SynchronizationState, long, long, bool), btcsignals::null_value>::operator()<SynchronizationState&, long&, long&, bool&>(SynchronizationState&, long&, long&, bool&) const Line | Count | Source | 202 | 42.3k | { | 203 | 42.3k | std::vector<std::shared_ptr<connection_holder>> connections; | 204 | 42.3k | { | 205 | 42.3k | LOCK(m_mutex); | 206 | 42.3k | connections = m_connections; | 207 | 42.3k | } | 208 | 42.3k | if constexpr (std::is_void_v<result_type>) { | 209 | 42.3k | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 210 | 42.3k | "Callback result type must be equal to the combiner result type (void)."); | 211 | 42.3k | for (const auto& connection : connections) { Branch (211:41): [True: 0, False: 42.3k]
| 212 | 0 | if (connection->connected()) { Branch (212:21): [True: 0, False: 0]
| 213 | 0 | connection->m_callback(args...); | 214 | 0 | } | 215 | 0 | } | 216 | | } else { | 217 | | static_assert(std::is_same_v<Combiner, any_of>, | 218 | | "only the any_of combiner is supported and hard-coded into this functor."); | 219 | | static_assert(std::is_same_v<result_type, typename function_type::result_type>, | 220 | | "Callback result type must be equal to the combiner result type (bool)."); | 221 | | result_type ret{false}; | 222 | | for (const auto& connection : connections) { | 223 | | if (connection->connected()) { | 224 | | ret |= connection->m_callback(args...); | 225 | | } | 226 | | } | 227 | | return ret; | 228 | | } | 229 | 42.3k | } |
Unexecuted instantiation: void btcsignals::signal<void (wallet::ScriptPubKeyMan const*, long), btcsignals::null_value>::operator()<wallet::DescriptorScriptPubKeyMan*, unsigned long&>(wallet::DescriptorScriptPubKeyMan*&&, unsigned long&) const Unexecuted instantiation: void btcsignals::signal<void (wallet::CWallet*), btcsignals::null_value>::operator()<wallet::CWallet*>(wallet::CWallet*&&) const Unexecuted instantiation: void btcsignals::signal<void (transaction_identifier<false> const&, ChangeType), btcsignals::null_value>::operator()<transaction_identifier<false> const&, ChangeType>(transaction_identifier<false> const&, ChangeType&&) const Unexecuted instantiation: void btcsignals::signal<void (transaction_identifier<false> const&, ChangeType), btcsignals::null_value>::operator()<transaction_identifier<false>&, ChangeType>(transaction_identifier<false>&, ChangeType&&) const Unexecuted instantiation: void btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int), btcsignals::null_value>::operator()<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, int&&) const Unexecuted instantiation: void btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int), btcsignals::null_value>::operator()<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int const&>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, int const&) const Unexecuted instantiation: void btcsignals::signal<void (std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType), btcsignals::null_value>::operator()<std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool&, wallet::AddressPurpose, ChangeType>(std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool&, wallet::AddressPurpose&&, ChangeType&&) const Unexecuted instantiation: void btcsignals::signal<void (std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType), btcsignals::null_value>::operator()<std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, char const (&) [1], bool, wallet::AddressPurpose, ChangeType>(std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, char const (&) [1], bool&&, wallet::AddressPurpose&&, ChangeType&&) const |
230 | | |
231 | | /* |
232 | | * Connect a new callback to the signal. A forwarding callable accepts |
233 | | * anything that can be stored in a std::function. |
234 | | */ |
235 | | template <typename Callable> |
236 | | connection connect(Callable&& func) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex) |
237 | 108 | { |
238 | 108 | LOCK(m_mutex); |
239 | | |
240 | | // Garbage-collect disconnected connections to prevent unbounded growth |
241 | 108 | std::erase_if(m_connections, [](const auto& holder) { return !holder->connected(); });auto btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), btcsignals::null_value>::connect<void (&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>(void (&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&))::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), btcsignals::null_value>::connection_holder> const&) constLine | Count | Source | 241 | 27 | std::erase_if(m_connections, [](const auto& holder) { return !holder->connected(); }); |
Unexecuted instantiation: init.cpp:auto btcsignals::signal<void (SynchronizationState, CBlockIndex const&, double), btcsignals::null_value>::connect<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_9>(AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_9&&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (SynchronizationState, CBlockIndex const&, double), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (SynchronizationState, CBlockIndex const&, double), btcsignals::null_value>::connection_holder> const&) constUnexecuted instantiation: auto btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), btcsignals::null_value>::connect<std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>&>(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), btcsignals::null_value>::connection_holder> const&) constUnexecuted instantiation: auto btcsignals::signal<void (bilingual_str const&, unsigned int), btcsignals::null_value>::connect<std::function<void (bilingual_str const&, unsigned int)>&>(std::function<void (bilingual_str const&, unsigned int)>&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (bilingual_str const&, unsigned int), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (bilingual_str const&, unsigned int), btcsignals::null_value>::connection_holder> const&) constUnexecuted instantiation: auto btcsignals::signal<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int), btcsignals::any_of>::connect<std::function<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)>&>(std::function<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)>&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int), btcsignals::any_of>::connection_holder> >(std::shared_ptr<btcsignals::signal<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int), btcsignals::any_of>::connection_holder> const&) constUnexecuted instantiation: auto btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool), btcsignals::null_value>::connect<std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool)>&>(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool)>&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool), btcsignals::null_value>::connection_holder> const&) constUnexecuted instantiation: auto btcsignals::signal<void (), btcsignals::null_value>::connect<std::function<void ()>&>(std::function<void ()>&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (), btcsignals::null_value>::connection_holder> const&) constUnexecuted instantiation: auto btcsignals::signal<void (int), btcsignals::null_value>::connect<std::function<void (int)>&>(std::function<void (int)>&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (int), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (int), btcsignals::null_value>::connection_holder> const&) constUnexecuted instantiation: auto btcsignals::signal<void (bool), btcsignals::null_value>::connect<std::function<void (bool)>&>(std::function<void (bool)>&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (bool), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (bool), btcsignals::null_value>::connection_holder> const&) constUnexecuted instantiation: interfaces.cpp:auto btcsignals::signal<void (SynchronizationState, CBlockIndex const&, double), btcsignals::null_value>::connect<node::(anonymous namespace)::NodeImpl::handleNotifyBlockTip(std::function<void (SynchronizationState, interfaces::BlockTip, double)>)::{lambda(SynchronizationState, CBlockIndex const&, double)#1}>(node::(anonymous namespace)::NodeImpl::handleNotifyBlockTip(std::function<void (SynchronizationState, interfaces::BlockTip, double)>)::{lambda(SynchronizationState, CBlockIndex const&, double)#1}&&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (SynchronizationState, CBlockIndex const&, double), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (SynchronizationState, CBlockIndex const&, double), btcsignals::null_value>::connection_holder> const&) constUnexecuted instantiation: interfaces.cpp:auto btcsignals::signal<void (SynchronizationState, long, long, bool), btcsignals::null_value>::connect<node::(anonymous namespace)::NodeImpl::handleNotifyHeaderTip(std::function<void (SynchronizationState, interfaces::BlockTip, bool)>)::{lambda(SynchronizationState, long, long, bool)#1}>(node::(anonymous namespace)::NodeImpl::handleNotifyHeaderTip(std::function<void (SynchronizationState, interfaces::BlockTip, bool)>)::{lambda(SynchronizationState, long, long, bool)#1}&&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (SynchronizationState, long, long, bool), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (SynchronizationState, long, long, bool), btcsignals::null_value>::connection_holder> const&) constUnexecuted instantiation: auto btcsignals::signal<void (bilingual_str const&, unsigned int), btcsignals::null_value>::connect<void (&)(bilingual_str const&, unsigned int)>(void (&)(bilingual_str const&, unsigned int))::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (bilingual_str const&, unsigned int), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (bilingual_str const&, unsigned int), btcsignals::null_value>::connection_holder> const&) constUnexecuted instantiation: auto btcsignals::signal<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int), btcsignals::any_of>::connect<bool (&)(bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)>(bool (&)(bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int))::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int), btcsignals::any_of>::connection_holder> >(std::shared_ptr<btcsignals::signal<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int), btcsignals::any_of>::connection_holder> const&) constUnexecuted instantiation: auto btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int), btcsignals::null_value>::connect<std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)>&>(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)>&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int), btcsignals::null_value>::connection_holder> const&) constUnexecuted instantiation: interfaces.cpp:auto btcsignals::signal<void (wallet::CWallet*), btcsignals::null_value>::connect<wallet::(anonymous namespace)::WalletImpl::handleStatusChanged(std::function<void ()>)::{lambda(wallet::CWallet*)#1}>(wallet::(anonymous namespace)::WalletImpl::handleStatusChanged(std::function<void ()>)::{lambda(wallet::CWallet*)#1}&&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (wallet::CWallet*), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (wallet::CWallet*), btcsignals::null_value>::connection_holder> const&) constUnexecuted instantiation: interfaces.cpp:auto btcsignals::signal<void (std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType), btcsignals::null_value>::connect<wallet::(anonymous namespace)::WalletImpl::handleAddressBookChanged(std::function<void (std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType)>)::{lambda(std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType)#1}>(wallet::(anonymous namespace)::WalletImpl::handleAddressBookChanged(std::function<void (std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType)>)::{lambda(std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType)#1}&&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType), btcsignals::null_value>::connection_holder> const&) constUnexecuted instantiation: interfaces.cpp:auto btcsignals::signal<void (transaction_identifier<false> const&, ChangeType), btcsignals::null_value>::connect<wallet::(anonymous namespace)::WalletImpl::handleTransactionChanged(std::function<void (transaction_identifier<false> const&, ChangeType)>)::{lambda(transaction_identifier<false> const&, ChangeType)#1}>(wallet::(anonymous namespace)::WalletImpl::handleTransactionChanged(std::function<void (transaction_identifier<false> const&, ChangeType)>)::{lambda(transaction_identifier<false> const&, ChangeType)#1}&&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (transaction_identifier<false> const&, ChangeType), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (transaction_identifier<false> const&, ChangeType), btcsignals::null_value>::connection_holder> const&) constUnexecuted instantiation: wallet.cpp:auto btcsignals::signal<void (), btcsignals::null_value>::connect<wallet::CWallet::ConnectScriptPubKeyManNotifiers()::$_0>(wallet::CWallet::ConnectScriptPubKeyManNotifiers()::$_0&&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (), btcsignals::null_value>::connection_holder> const&) constUnexecuted instantiation: wallet.cpp:auto btcsignals::signal<void (wallet::ScriptPubKeyMan const*, long), btcsignals::null_value>::connect<wallet::CWallet::ConnectScriptPubKeyManNotifiers()::$_1>(wallet::CWallet::ConnectScriptPubKeyManNotifiers()::$_1&&)::{lambda(auto:1 const&)#1}::operator()<std::shared_ptr<btcsignals::signal<void (wallet::ScriptPubKeyMan const*, long), btcsignals::null_value>::connection_holder> >(std::shared_ptr<btcsignals::signal<void (wallet::ScriptPubKeyMan const*, long), btcsignals::null_value>::connection_holder> const&) const |
242 | | |
243 | 108 | const auto& entry = m_connections.emplace_back(std::make_shared<connection_holder>(std::forward<Callable>(func))); |
244 | 108 | return connection(entry); |
245 | 108 | } btcsignals::connection btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), btcsignals::null_value>::connect<void (&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>(void (&)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)) Line | Count | Source | 237 | 54 | { | 238 | 54 | LOCK(m_mutex); | 239 | | | 240 | | // Garbage-collect disconnected connections to prevent unbounded growth | 241 | 54 | std::erase_if(m_connections, [](const auto& holder) { return !holder->connected(); }); | 242 | | | 243 | 54 | const auto& entry = m_connections.emplace_back(std::make_shared<connection_holder>(std::forward<Callable>(func))); | 244 | 54 | return connection(entry); | 245 | 54 | } |
Unexecuted instantiation: init.cpp:btcsignals::connection btcsignals::signal<void (SynchronizationState, CBlockIndex const&, double), btcsignals::null_value>::connect<AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_9>(AppInitMain(node::NodeContext&, interfaces::BlockAndHeaderTipInfo*)::$_9&&) Unexecuted instantiation: btcsignals::connection btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), btcsignals::null_value>::connect<std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>&>(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>&) Unexecuted instantiation: btcsignals::connection btcsignals::signal<void (bilingual_str const&, unsigned int), btcsignals::null_value>::connect<std::function<void (bilingual_str const&, unsigned int)>&>(std::function<void (bilingual_str const&, unsigned int)>&) Unexecuted instantiation: btcsignals::connection btcsignals::signal<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int), btcsignals::any_of>::connect<std::function<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)>&>(std::function<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)>&) Unexecuted instantiation: btcsignals::connection btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool), btcsignals::null_value>::connect<std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool)>&>(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, bool)>&) Unexecuted instantiation: btcsignals::connection btcsignals::signal<void (), btcsignals::null_value>::connect<std::function<void ()>&>(std::function<void ()>&) Unexecuted instantiation: btcsignals::connection btcsignals::signal<void (int), btcsignals::null_value>::connect<std::function<void (int)>&>(std::function<void (int)>&) Unexecuted instantiation: btcsignals::connection btcsignals::signal<void (bool), btcsignals::null_value>::connect<std::function<void (bool)>&>(std::function<void (bool)>&) Unexecuted instantiation: interfaces.cpp:btcsignals::connection btcsignals::signal<void (SynchronizationState, CBlockIndex const&, double), btcsignals::null_value>::connect<node::(anonymous namespace)::NodeImpl::handleNotifyBlockTip(std::function<void (SynchronizationState, interfaces::BlockTip, double)>)::{lambda(SynchronizationState, CBlockIndex const&, double)#1}>(node::(anonymous namespace)::NodeImpl::handleNotifyBlockTip(std::function<void (SynchronizationState, interfaces::BlockTip, double)>)::{lambda(SynchronizationState, CBlockIndex const&, double)#1}&&)Unexecuted instantiation: interfaces.cpp:btcsignals::connection btcsignals::signal<void (SynchronizationState, long, long, bool), btcsignals::null_value>::connect<node::(anonymous namespace)::NodeImpl::handleNotifyHeaderTip(std::function<void (SynchronizationState, interfaces::BlockTip, bool)>)::{lambda(SynchronizationState, long, long, bool)#1}>(node::(anonymous namespace)::NodeImpl::handleNotifyHeaderTip(std::function<void (SynchronizationState, interfaces::BlockTip, bool)>)::{lambda(SynchronizationState, long, long, bool)#1}&&)btcsignals::connection btcsignals::signal<void (bilingual_str const&, unsigned int), btcsignals::null_value>::connect<void (&)(bilingual_str const&, unsigned int)>(void (&)(bilingual_str const&, unsigned int)) Line | Count | Source | 237 | 27 | { | 238 | 27 | LOCK(m_mutex); | 239 | | | 240 | | // Garbage-collect disconnected connections to prevent unbounded growth | 241 | 27 | std::erase_if(m_connections, [](const auto& holder) { return !holder->connected(); }); | 242 | | | 243 | 27 | const auto& entry = m_connections.emplace_back(std::make_shared<connection_holder>(std::forward<Callable>(func))); | 244 | 27 | return connection(entry); | 245 | 27 | } |
btcsignals::connection btcsignals::signal<bool (bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int), btcsignals::any_of>::connect<bool (&)(bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)>(bool (&)(bilingual_str const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)) Line | Count | Source | 237 | 27 | { | 238 | 27 | LOCK(m_mutex); | 239 | | | 240 | | // Garbage-collect disconnected connections to prevent unbounded growth | 241 | 27 | std::erase_if(m_connections, [](const auto& holder) { return !holder->connected(); }); | 242 | | | 243 | 27 | const auto& entry = m_connections.emplace_back(std::make_shared<connection_holder>(std::forward<Callable>(func))); | 244 | 27 | return connection(entry); | 245 | 27 | } |
Unexecuted instantiation: btcsignals::connection btcsignals::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int), btcsignals::null_value>::connect<std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)>&>(std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)>&) Unexecuted instantiation: interfaces.cpp:btcsignals::connection btcsignals::signal<void (wallet::CWallet*), btcsignals::null_value>::connect<wallet::(anonymous namespace)::WalletImpl::handleStatusChanged(std::function<void ()>)::{lambda(wallet::CWallet*)#1}>(wallet::(anonymous namespace)::WalletImpl::handleStatusChanged(std::function<void ()>)::{lambda(wallet::CWallet*)#1}&&)Unexecuted instantiation: interfaces.cpp:btcsignals::connection btcsignals::signal<void (std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType), btcsignals::null_value>::connect<wallet::(anonymous namespace)::WalletImpl::handleAddressBookChanged(std::function<void (std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType)>)::{lambda(std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType)#1}>(wallet::(anonymous namespace)::WalletImpl::handleAddressBookChanged(std::function<void (std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType)>)::{lambda(std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, wallet::AddressPurpose, ChangeType)#1}&&)Unexecuted instantiation: interfaces.cpp:btcsignals::connection btcsignals::signal<void (transaction_identifier<false> const&, ChangeType), btcsignals::null_value>::connect<wallet::(anonymous namespace)::WalletImpl::handleTransactionChanged(std::function<void (transaction_identifier<false> const&, ChangeType)>)::{lambda(transaction_identifier<false> const&, ChangeType)#1}>(wallet::(anonymous namespace)::WalletImpl::handleTransactionChanged(std::function<void (transaction_identifier<false> const&, ChangeType)>)::{lambda(transaction_identifier<false> const&, ChangeType)#1}&&)Unexecuted instantiation: wallet.cpp:btcsignals::connection btcsignals::signal<void (), btcsignals::null_value>::connect<wallet::CWallet::ConnectScriptPubKeyManNotifiers()::$_0>(wallet::CWallet::ConnectScriptPubKeyManNotifiers()::$_0&&) Unexecuted instantiation: wallet.cpp:btcsignals::connection btcsignals::signal<void (wallet::ScriptPubKeyMan const*, long), btcsignals::null_value>::connect<wallet::CWallet::ConnectScriptPubKeyManNotifiers()::$_1>(wallet::CWallet::ConnectScriptPubKeyManNotifiers()::$_1&&) |
246 | | |
247 | | /* |
248 | | * Returns true if there are no enabled callbacks |
249 | | */ |
250 | | [[nodiscard]] bool empty() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex) |
251 | 150k | { |
252 | 150k | LOCK(m_mutex); |
253 | 150k | return std::ranges::none_of(m_connections, [](const auto& holder) { |
254 | 0 | return holder->connected(); |
255 | 0 | }); |
256 | 150k | } |
257 | | }; |
258 | | |
259 | | } // namespace btcsignals |
260 | | |
261 | | #endif // BITCOIN_UTIL_BTCSIGNALS_H |