Coverage Report

Created: 2026-07-14 18:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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&) const
Line
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&) const
Unexecuted 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&) const
Unexecuted 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&) const
Unexecuted 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&) const
Unexecuted 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&) const
Unexecuted 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&) const
Unexecuted 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&) const
Unexecuted 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&) const
Unexecuted 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&) const
Unexecuted 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&) const
Unexecuted 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&) const
Unexecuted 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&) const
Unexecuted 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&) const
Unexecuted 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&) const
Unexecuted 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&) const
Unexecuted 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&) const
Unexecuted 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&) const
Unexecuted 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