/****************************************************************************** * Icinga 2 * * Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/) * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software Foundation * * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * ******************************************************************************/ #ifndef REGISTRY_H #define REGISTRY_H #include "base/i2-base.h" #include "base/singleton.h" #include "base/qstring.h" #include #include #include #include #include namespace icinga { /** * A registry. * * @ingroup base */ template class Registry { public: typedef std::map ItemMap; static Registry *GetInstance(void) { return Singleton >::GetInstance(); } void RegisterIfNew(const String& name, const T& item) { boost::mutex::scoped_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) { boost::mutex::scoped_lock lock(m_Mutex); RegisterInternal(name, item, lock); } void Unregister(const String& name) { size_t erased; { boost::mutex::scoped_lock lock(m_Mutex); erased = m_Items.erase(name); } if (erased > 0) OnUnregistered(name); } void Clear(void) { typename Registry::ItemMap items; { boost::mutex::scoped_lock lock(m_Mutex); items = m_Items; } String name; BOOST_FOREACH(boost::tie(name, boost::tuples::ignore), items) { OnUnregistered(name); } { boost::mutex::scoped_lock lock(m_Mutex); m_Items.clear(); } } T GetItem(const String& name) const { boost::mutex::scoped_lock lock(m_Mutex); typename ItemMap::const_iterator it; it = m_Items.find(name); if (it == m_Items.end()) return T(); return it->second; } ItemMap GetItems(void) const { boost::mutex::scoped_lock lock(m_Mutex); return m_Items; /* Makes a copy of the map. */ } boost::signals2::signal OnRegistered; boost::signals2::signal OnUnregistered; private: mutable boost::mutex m_Mutex; typename Registry::ItemMap m_Items; void RegisterInternal(const String& name, const T& item, boost::mutex::scoped_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 */