/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ #ifndef REGISTRY_H #define REGISTRY_H #include "base/i2-base.hpp" #include "base/string.hpp" #include #include #include namespace icinga { /** * A registry. * * @ingroup base */ template class Registry { public: typedef std::map ItemMap; void RegisterIfNew(const String& name, const T& item) { std::unique_lock 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 lock(m_Mutex); RegisterInternal(name, item, lock); } void Unregister(const String& name) { size_t erased; { std::unique_lock lock(m_Mutex); erased = m_Items.erase(name); } if (erased > 0) OnUnregistered(name); } void Clear() { typename Registry::ItemMap items; { std::unique_lock lock(m_Mutex); items = m_Items; } for (const auto& kv : items) { OnUnregistered(kv.first); } { std::unique_lock lock(m_Mutex); m_Items.clear(); } } T GetItem(const String& name) const { std::unique_lock 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 lock(m_Mutex); return m_Items; /* Makes a copy of the map. */ } boost::signals2::signal OnRegistered; boost::signals2::signal OnUnregistered; private: mutable std::mutex m_Mutex; typename Registry::ItemMap m_Items; void RegisterInternal(const String& name, const T& item, std::unique_lock& 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 */