diff --git a/nano/lib/CMakeLists.txt b/nano/lib/CMakeLists.txt index f679c7b913..d16a8d336f 100644 --- a/nano/lib/CMakeLists.txt +++ b/nano/lib/CMakeLists.txt @@ -52,6 +52,7 @@ add_library( memory.cpp numbers.hpp numbers.cpp + observer_set.hpp optional_ptr.hpp rate_limiting.hpp rate_limiting.cpp diff --git a/nano/lib/observer_set.hpp b/nano/lib/observer_set.hpp new file mode 100644 index 0000000000..de57a80bbe --- /dev/null +++ b/nano/lib/observer_set.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include +#include + +#include +#include + +namespace nano +{ +template +class observer_set final +{ +public: + void add (std::function const & observer_a) + { + nano::lock_guard lock (mutex); + observers.push_back (observer_a); + } + + void notify (T... args) const + { + nano::unique_lock lock (mutex); + auto observers_copy = observers; + lock.unlock (); + + for (auto & i : observers_copy) + { + i (args...); + } + } + + bool empty () const + { + nano::lock_guard lock (mutex); + return observers.empty (); + } + + std::unique_ptr collect_container_info (std::string const & name) const + { + nano::unique_lock lock (mutex); + auto count = observers.size (); + lock.unlock (); + auto sizeof_element = sizeof (typename decltype (observers)::value_type); + auto composite = std::make_unique (name); + composite->add_component (std::make_unique (container_info{ "observers", count, sizeof_element })); + return composite; + } + +private: + mutable nano::mutex mutex{ mutex_identifier (mutexes::observer_set) }; + std::vector> observers; +}; + +} diff --git a/nano/lib/stats.cpp b/nano/lib/stats.cpp index 266242ec0e..e5320493b9 100644 --- a/nano/lib/stats.cpp +++ b/nano/lib/stats.cpp @@ -421,7 +421,7 @@ void nano::stat::update (uint32_t key_a, uint64_t value) entry->samples.push_back (entry->sample_current); entry->sample_current.set_value (0); - if (!entry->sample_observers.observers.empty ()) + if (!entry->sample_observers.empty ()) { auto snapshot (entry->samples); entry->sample_observers.notify (snapshot); diff --git a/nano/lib/stats.hpp b/nano/lib/stats.hpp index 3250418173..7748d20c46 100644 --- a/nano/lib/stats.hpp +++ b/nano/lib/stats.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include diff --git a/nano/lib/utility.hpp b/nano/lib/utility.hpp index 34167a2cba..0e0da30fab 100644 --- a/nano/lib/utility.hpp +++ b/nano/lib/utility.hpp @@ -147,45 +147,6 @@ std::string generate_stacktrace (); std::size_t get_file_descriptor_limit (); void set_file_descriptor_limit (std::size_t limit); -template -class observer_set final -{ -public: - void add (std::function const & observer_a) - { - nano::lock_guard lock (mutex); - observers.push_back (observer_a); - } - void notify (T... args) - { - nano::unique_lock lock (mutex); - auto observers_copy = observers; - lock.unlock (); - - for (auto & i : observers_copy) - { - i (args...); - } - } - nano::mutex mutex{ mutex_identifier (mutexes::observer_set) }; - std::vector> observers; -}; - -template -std::unique_ptr collect_container_info (observer_set & observer_set, std::string const & name) -{ - size_t count = 0; - { - nano::lock_guard lock (observer_set.mutex); - count = observer_set.observers.size (); - } - - auto sizeof_element = sizeof (typename decltype (observer_set.observers)::value_type); - auto composite = std::make_unique (name); - composite->add_component (std::make_unique (container_info{ "observers", count, sizeof_element })); - return composite; -} - void remove_all_files_in_dir (boost::filesystem::path const & dir); void move_all_files_to_dir (boost::filesystem::path const & from, boost::filesystem::path const & to); diff --git a/nano/lib/work.cpp b/nano/lib/work.cpp index f6afc6ca39..1bbcd13304 100644 --- a/nano/lib/work.cpp +++ b/nano/lib/work.cpp @@ -241,6 +241,6 @@ std::unique_ptr nano::collect_container_info (wo auto sizeof_element = sizeof (decltype (work_pool.pending)::value_type); auto composite = std::make_unique (name); composite->add_component (std::make_unique (container_info{ "pending", count, sizeof_element })); - composite->add_component (collect_container_info (work_pool.work_observers, "work_observers")); + composite->add_component (work_pool.work_observers.collect_container_info ("work_observers")); return composite; } diff --git a/nano/lib/work.hpp b/nano/lib/work.hpp index 15ae1291ab..70df3b8144 100644 --- a/nano/lib/work.hpp +++ b/nano/lib/work.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include diff --git a/nano/node/node_observers.cpp b/nano/node/node_observers.cpp index 5864dbce8d..e179a53d13 100644 --- a/nano/node/node_observers.cpp +++ b/nano/node/node_observers.cpp @@ -3,14 +3,14 @@ std::unique_ptr nano::collect_container_info (nano::node_observers & node_observers, std::string const & name) { auto composite = std::make_unique (name); - composite->add_component (collect_container_info (node_observers.blocks, "blocks")); - composite->add_component (collect_container_info (node_observers.wallet, "wallet")); - composite->add_component (collect_container_info (node_observers.vote, "vote")); - composite->add_component (collect_container_info (node_observers.active_started, "active_started")); - composite->add_component (collect_container_info (node_observers.active_stopped, "active_stopped")); - composite->add_component (collect_container_info (node_observers.account_balance, "account_balance")); - composite->add_component (collect_container_info (node_observers.endpoint, "endpoint")); - composite->add_component (collect_container_info (node_observers.disconnect, "disconnect")); - composite->add_component (collect_container_info (node_observers.work_cancel, "work_cancel")); + composite->add_component (node_observers.blocks.collect_container_info ("blocks")); + composite->add_component (node_observers.wallet.collect_container_info ("wallet")); + composite->add_component (node_observers.vote.collect_container_info ("vote")); + composite->add_component (node_observers.active_started.collect_container_info ("active_started")); + composite->add_component (node_observers.active_stopped.collect_container_info ("active_stopped")); + composite->add_component (node_observers.account_balance.collect_container_info ("account_balance")); + composite->add_component (node_observers.endpoint.collect_container_info ("endpoint")); + composite->add_component (node_observers.disconnect.collect_container_info ("disconnect")); + composite->add_component (node_observers.work_cancel.collect_container_info ("work_cancel")); return composite; }