]> granicus.if.org Git - icinga2/blob - lib/base/registry.hpp
Merge pull request #7185 from Icinga/bugfix/gelfwriter-wrong-log-facility
[icinga2] / lib / base / registry.hpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
3 #ifndef REGISTRY_H
4 #define REGISTRY_H
5
6 #include "base/i2-base.hpp"
7 #include "base/string.hpp"
8 #include <boost/thread/mutex.hpp>
9 #include <boost/signals2.hpp>
10 #include <map>
11
12 namespace icinga
13 {
14
15 /**
16  * A registry.
17  *
18  * @ingroup base
19  */
20 template<typename U, typename T>
21 class Registry
22 {
23 public:
24         typedef std::map<String, T> ItemMap;
25
26         void RegisterIfNew(const String& name, const T& item)
27         {
28                 boost::mutex::scoped_lock lock(m_Mutex);
29
30                 if (m_Items.find(name) != m_Items.end())
31                         return;
32
33                 RegisterInternal(name, item, lock);
34         }
35
36         void Register(const String& name, const T& item)
37         {
38                 boost::mutex::scoped_lock lock(m_Mutex);
39
40                 RegisterInternal(name, item, lock);
41         }
42
43         void Unregister(const String& name)
44         {
45                 size_t erased;
46
47                 {
48                         boost::mutex::scoped_lock lock(m_Mutex);
49                         erased = m_Items.erase(name);
50                 }
51
52                 if (erased > 0)
53                         OnUnregistered(name);
54         }
55
56         void Clear()
57         {
58                 typename Registry<U, T>::ItemMap items;
59
60                 {
61                         boost::mutex::scoped_lock lock(m_Mutex);
62                         items = m_Items;
63                 }
64
65                 for (const auto& kv : items) {
66                         OnUnregistered(kv.first);
67                 }
68
69                 {
70                         boost::mutex::scoped_lock lock(m_Mutex);
71                         m_Items.clear();
72                 }
73         }
74
75         T GetItem(const String& name) const
76         {
77                 boost::mutex::scoped_lock lock(m_Mutex);
78
79                 auto it = m_Items.find(name);
80
81                 if (it == m_Items.end())
82                         return T();
83
84                 return it->second;
85         }
86
87         ItemMap GetItems() const
88         {
89                 boost::mutex::scoped_lock lock(m_Mutex);
90
91                 return m_Items; /* Makes a copy of the map. */
92         }
93
94         boost::signals2::signal<void (const String&, const T&)> OnRegistered;
95         boost::signals2::signal<void (const String&)> OnUnregistered;
96
97 private:
98         mutable boost::mutex m_Mutex;
99         typename Registry<U, T>::ItemMap m_Items;
100
101         void RegisterInternal(const String& name, const T& item, boost::mutex::scoped_lock& lock)
102         {
103                 bool old_item = false;
104
105                 if (m_Items.erase(name) > 0)
106                         old_item = true;
107
108                 m_Items[name] = item;
109
110                 lock.unlock();
111
112                 if (old_item)
113                         OnUnregistered(name);
114
115                 OnRegistered(name, item);
116         }
117 };
118
119 }
120
121 #endif /* REGISTRY_H */