summaryrefslogtreecommitdiffstats
path: root/lib/base/registry.hpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 11:32:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 11:32:39 +0000
commit56ae875861ab260b80a030f50c4aff9f9dc8fff0 (patch)
tree531412110fc901a5918c7f7442202804a83cada9 /lib/base/registry.hpp
parentInitial commit. (diff)
downloadicinga2-upstream.tar.xz
icinga2-upstream.zip
Adding upstream version 2.14.2.upstream/2.14.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/base/registry.hpp')
-rw-r--r--lib/base/registry.hpp121
1 files changed, 121 insertions, 0 deletions
diff --git a/lib/base/registry.hpp b/lib/base/registry.hpp
new file mode 100644
index 0000000..c13f7e1
--- /dev/null
+++ b/lib/base/registry.hpp
@@ -0,0 +1,121 @@
+/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
+
+#ifndef REGISTRY_H
+#define REGISTRY_H
+
+#include "base/i2-base.hpp"
+#include "base/string.hpp"
+#include <boost/signals2.hpp>
+#include <map>
+#include <mutex>
+
+namespace icinga
+{
+
+/**
+ * A registry.
+ *
+ * @ingroup base
+ */
+template<typename U, typename T>
+class Registry
+{
+public:
+ typedef std::map<String, T> ItemMap;
+
+ void RegisterIfNew(const String& name, const T& item)
+ {
+ std::unique_lock<std::mutex> lock(m_Mutex);
+
+ if (m_Items.find(name) != m_Items.end())
+ return;
+
+ RegisterInternal(name, item, lock);
+ }
+
+ void Register(const String& name, const T& item)
+ {
+ std::unique_lock<std::mutex> lock(m_Mutex);
+
+ RegisterInternal(name, item, lock);
+ }
+
+ void Unregister(const String& name)
+ {
+ size_t erased;
+
+ {
+ std::unique_lock<std::mutex> lock(m_Mutex);
+ erased = m_Items.erase(name);
+ }
+
+ if (erased > 0)
+ OnUnregistered(name);
+ }
+
+ void Clear()
+ {
+ typename Registry<U, T>::ItemMap items;
+
+ {
+ std::unique_lock<std::mutex> lock(m_Mutex);
+ items = m_Items;
+ }
+
+ for (const auto& kv : items) {
+ OnUnregistered(kv.first);
+ }
+
+ {
+ std::unique_lock<std::mutex> lock(m_Mutex);
+ m_Items.clear();
+ }
+ }
+
+ T GetItem(const String& name) const
+ {
+ std::unique_lock<std::mutex> lock(m_Mutex);
+
+ auto it = m_Items.find(name);
+
+ if (it == m_Items.end())
+ return T();
+
+ return it->second;
+ }
+
+ ItemMap GetItems() const
+ {
+ std::unique_lock<std::mutex> lock(m_Mutex);
+
+ return m_Items; /* Makes a copy of the map. */
+ }
+
+ boost::signals2::signal<void (const String&, const T&)> OnRegistered;
+ boost::signals2::signal<void (const String&)> OnUnregistered;
+
+private:
+ mutable std::mutex m_Mutex;
+ typename Registry<U, T>::ItemMap m_Items;
+
+ void RegisterInternal(const String& name, const T& item, std::unique_lock<std::mutex>& lock)
+ {
+ bool old_item = false;
+
+ if (m_Items.erase(name) > 0)
+ old_item = true;
+
+ m_Items[name] = item;
+
+ lock.unlock();
+
+ if (old_item)
+ OnUnregistered(name);
+
+ OnRegistered(name, item);
+ }
+};
+
+}
+
+#endif /* REGISTRY_H */