5#ifndef BITCOIN_UTIL_BTCSIGNALS_H
6#define BITCOIN_UTIL_BTCSIGNALS_H
55template <
typename Signature,
typename Combiner = null_value>
59#ifdef __cpp_lib_atomic_shared_ptr
77 std::shared_ptr<T>
load() const noexcept {
return std::atomic_load(&
m_ptr); }
78 void store(std::shared_ptr<T> ptr)
noexcept { std::atomic_store(&
m_ptr, std::move(ptr)); }
90 template <
typename Signature,
typename Combiner>
194template <
typename Signature,
typename Combiner>
203 template <
typename Callable>
211 std::shared_ptr<const function_type>
callback()
const
213 return std::static_pointer_cast<const function_type>(
load());
253 std::vector<std::shared_ptr<connection_holder>>
connections;
258 if constexpr (std::is_void_v<result_type>) {
259 static_assert(std::is_same_v<result_type, typename function_type::result_type>,
260 "Callback result type must be equal to the combiner result type (void).");
264 if (
const auto callback{
connection->callback()}) {
265 (*callback)(
args...);
269 static_assert(std::is_same_v<Combiner, any_of>,
270 "only the any_of combiner is supported and hard-coded into this functor.");
271 static_assert(std::is_same_v<result_type, typename function_type::result_type>,
272 "Callback result type must be equal to the combiner result type (bool).");
275 if (
const auto callback{
connection->callback()}) {
287 template <
typename Callable>
293 std::erase_if(m_connections, [](
const auto&
holder) {
return !
holder->connected(); });
295 const auto& entry = m_connections.emplace_back(std::make_shared<connection_holder>(std::forward<Callable>(func)));
305 return std::ranges::none_of(m_connections, [](
const auto&
holder) {
306 return holder->connected();
A combiner, which checks if at least one callback returned true.
detail::atomic_shared_ptr< const void > m_callback
Callback object, type-erased so connection does not depend on the signal type, and set to null by dis...
liveness(std::shared_ptr< const void > callback)
std::shared_ptr< const void > load() const
void disconnect()
If a callback is associated with this connection, prevent it from being called in the future.
std::shared_ptr< liveness > m_state
connections have shared_ptr-like copy and move semantics.
connection(std::shared_ptr< liveness > &&state)
Only a signal can create an enabled connection.
constexpr connection() noexcept=default
The default constructor creates a connection with no associated signal.
bool connected() const
Returns true if this connection was created by a signal and has not been disabled.
Substitute for the C++20 std::atomic<std::shared_ptr<T>> specialization on standard libraries that do...
atomic_shared_ptr(std::shared_ptr< T > ptr) noexcept
std::shared_ptr< T > m_ptr
atomic_shared_ptr & operator=(const atomic_shared_ptr &)=delete
void store(std::shared_ptr< T > ptr) noexcept
atomic_shared_ptr(const atomic_shared_ptr &)=delete
std::shared_ptr< T > load() const noexcept
The default combiner, which only returns void.
scoped_connection(scoped_connection &&) noexcept=default
scoped_connection(connection rhs) noexcept
std::function< Signature > function_type
std::vector< std::shared_ptr< connection_holder > > m_connections GUARDED_BY(m_mutex)
connection connect(Callable &&func) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Combiner::result_type result_type
constexpr signal() noexcept=default
bool empty() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
btcsignals is a simple mechanism for signaling events to multiple subscribers.
connection_holder(Callable &&callback)
std::shared_ptr< const function_type > callback() const
Return the callback, or null if disconnected.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.