]> granicus.if.org Git - icinga2/blob - lib/base/object.h
Fine-grained locks (WIP, Part 8).
[icinga2] / lib / base / object.h
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/)        *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #ifndef OBJECT_H
21 #define OBJECT_H
22
23 namespace icinga
24 {
25
26 class SharedPtrHolder;
27
28 /**
29  * Base class for all heap-allocated objects. At least one of its methods
30  * has to be virtual for RTTI to work.
31  *
32  * @ingroup base
33  */
34 class I2_BASE_API Object : public enable_shared_from_this<Object>
35 {
36 public:
37         typedef shared_ptr<Object> Ptr;
38         typedef weak_ptr<Object> WeakPtr;
39
40         /**
41          * Holds a shared pointer and provides support for implicit upcasts.
42          *
43          * @ingroup base
44          */
45         class SharedPtrHolder
46         {
47         public:
48                 /**
49                  * Constructor for the SharedPtrHolder class.
50                  *
51                  * @param object The shared pointer that should be used to
52                  *               construct this shared pointer holder.
53                  */
54                 explicit SharedPtrHolder(const Object::Ptr& object)
55                         : m_Object(object)
56                 { }
57
58                 /**
59                  * Retrieves a shared pointer for the object that is associated
60                  * this holder instance.
61                  *
62                  * @returns A shared pointer.
63                  */
64                 template<typename T>
65                 operator shared_ptr<T>(void) const
66                 {
67 #ifdef _DEBUG
68                         shared_ptr<T> other = dynamic_pointer_cast<T>(m_Object);
69                         assert(other);
70 #else /* _DEBUG */
71                         shared_ptr<T> other = static_pointer_cast<T>(m_Object);
72 #endif /* _DEBUG */
73
74                         return other;
75                 }
76
77                 /**
78                  * Retrieves a weak pointer for the object that is associated
79                  * with this holder instance.
80                  *
81                  * @returns A weak pointer.
82                  */
83                 template<typename T>
84                 operator weak_ptr<T>(void) const
85                 {
86                         return static_cast<shared_ptr<T> >(*this);
87                 }
88
89         private:
90                 Object::Ptr m_Object; /**< The object that belongs to this
91                                            holder instance */
92         };
93
94         SharedPtrHolder GetSelf(void);
95
96         recursive_mutex& GetMutex(void) const;
97
98 protected:
99         Object(void);
100         virtual ~Object(void);
101
102 private:
103         Object(const Object& other);
104         Object& operator=(const Object& rhs);
105
106         mutable recursive_mutex m_Mutex;
107 };
108
109 /**
110  * A scoped lock for Objects.
111  */
112 struct ObjectLock {
113 public:
114         ObjectLock(void)
115                 : m_Lock()
116         { }
117
118         ObjectLock(const Object::Ptr& object)
119                 : m_Lock()
120         {
121                 if (object)
122                         m_Lock = recursive_mutex::scoped_lock(object->GetMutex());
123         }
124
125         ObjectLock(const Object *object)
126                 : m_Lock()
127         {
128                 if (object)
129                         m_Lock = recursive_mutex::scoped_lock(object->GetMutex());
130         }
131
132         void Unlock(void)
133         {
134                 m_Lock = recursive_mutex::scoped_lock();
135         }
136
137 private:
138         recursive_mutex::scoped_lock m_Lock;
139 };
140
141 /**
142  * Compares a weak pointer with a raw pointer.
143  *
144  * @ingroup base
145  */
146 template<class T>
147 struct WeakPtrEqual
148 {
149 private:
150         const void *m_Ref; /**< The object. */
151
152 public:
153         /**
154          * Constructor for the WeakPtrEqual class.
155          *
156          * @param ref The object that should be compared with the weak pointer.
157          */
158         WeakPtrEqual(const void *ref) : m_Ref(ref) { }
159
160         /**
161          * Compares the two pointers.
162          *
163          * @param wref The weak pointer.
164          * @returns true if the pointers point to the same object, false otherwise.
165          */
166         bool operator()(const weak_ptr<T>& wref) const
167         {
168                 return (wref.lock().get() == static_cast<const T *>(m_Ref));
169         }
170 };
171
172 }
173
174 #endif /* OBJECT_H */