sigx++  2.0.1
lockable.h
Go to the documentation of this file.
1 #ifndef _SIGX_LOCKABLE_H_
2 #define _SIGX_LOCKABLE_H_
3 
4 /*
5  * Copyright 2008 Klaus Triendl
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the Free
19  * Software Foundation, 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21 */
22 
23 /*
24  * Inspired by Andrei Alexandrescu's article "volatile - Multithreaded
25  * Programmer's Best Friend":
26  * http://www.ddj.com/dept/cpp/184403766
27 */
28 
29 #include <tr1/type_traits>
30 #include <sigx/noncopyable.h>
31 #include <sigx/lockable_fwddecl.h>
32 #include <sigx/const_trait.h>
33 #include <sigx/volatile_trait.h>
34 
35 
36 namespace sigx
37 {
38 
50 template<typename T_mutex>
52 {
53  typedef T_mutex mutex_type;
54 
55 
56  mutex_type& mutex() const throw()
57  {
58  return m_mutex;
59  }
60 
61 protected:
63  m_mutex()
64  {}
65 
66 
69  mutable mutex_type m_mutex;
70 };
71 
72 
73 
90 template<typename T_type, typename T_mutex>
91 struct safe_lockable: public lockable_base<T_mutex>
92 {
93  // lock_acquirer can use interface methods
94  template<locking_policy I_policy, typename T_type1, typename T_mutex1, typename T_islockable> friend class lock_acquirer;
95 
97  // acquired_type = type to protect, 1:1 from T_type
98  typedef T_type acquired_type;
99  // volatile_type = make T_type volatile, even if T_type is a reference
100  // volatile T_type or volatile T_type&
102  // reference_type = reference to volatile-stripped T_type
103  // T_type&
104  typedef typename std::tr1::add_reference<typename volatile_trait<acquired_type>::remove>::type reference_type;
105  // volatile_reference_type = reference to volatile T_type, even if T_type is a reference
106  // volatile T_type&
107  typedef typename std::tr1::add_reference<volatile_type>::type volatile_reference_type;
108  // reference_type = reference to volatile-stripped T_type, even if T_type is a reference
109  // const T_type&
110  typedef typename std::tr1::add_reference<typename const_trait<reference_type>::add>::type const_reference_type;
111  // cv_reference_type = reference to cv-qualified T_type, even if T_type is a reference
112  // const volatile T_type&
113  typedef typename std::tr1::add_reference<typename const_trait<volatile_type>::add>::type cv_reference_type;
114  // apply const qualifier and reference to toplevel type, unchanged if toplevel type is a reference
115  typedef typename std::tr1::add_reference<typename std::tr1::add_const<acquired_type>::type>::type toplevel_const_reference_type;
116 
117 
123  parent_type(),
124  m_obj()
125  {}
126 
129  safe_lockable(toplevel_const_reference_type _a_value):
130  parent_type(),
131  m_obj(_a_value)
132  {}
133 
134 
135 protected:
138  volatile_reference_type access_volatile() throw()
139  {
140  return m_obj;
141  }
142 
145  reference_type access_nonvolatile() throw()
146  {
147  // volatile_cast m_obj
148  return const_cast<reference_type>(m_obj);
149  }
150 
153  cv_reference_type access_volatile() const throw()
154  {
155  return m_obj;
156  }
157 
160  const_reference_type access_nonvolatile() const throw()
161  {
162  // volatile_cast m_obj
163  return const_cast<const_reference_type>(m_obj);
164  }
165 
166 
167 private:
170  volatile_type m_obj;
171 };
172 
173 
176 template<typename T_type, typename T_mutex>
177 struct lockable: public safe_lockable<T_type, T_mutex>
178 {
181 
182 public:
188  parent_type()
189  {}
190 
193  lockable(toplevel_const_reference_type _a_value):
194  parent_type(_a_value)
195  {}
196 
197  // make safe_lockable's interface publicly available
200 };
201 
202 
203 
204 #if 0 // specializations for pointers
205 
214 template<typename T_mutex>
215 struct lockable<void*, T_mutex>: public lockable_base<T_mutex>
216 {
217  typedef void* acquired_type;
218  typedef T_mutex mutex_type;
219  typedef lockable_base<mutex_type> parent_type;
220  typedef lockable<acquired_type, mutex_type> type;
221  typedef typename volatile_trait<acquired_type>::add volatile_type;
222  typedef typename std::tr1::add_reference<typename volatile_trait<acquired_type>::remove>::type reference_type;
223  typedef typename std::tr1::add_reference<typename volatile_trait<acquired_type>::add>::type volatile_reference_type;
224  typedef typename std::tr1::add_reference<typename std::tr1::add_const<acquired_type>::type>::type take_type;
225 
226 
231  lockable(take_type _a_value = 0):
232  parent_type(),
233  m_obj(_a_value)
234  {}
235 
238  volatile_reference_type access_volatile()
239  {
240  return m_obj;
241  }
242 
245  reference_type access_nonvolatile()
246  {
247  // volatile_cast m_obj
248  return const_cast<reference_type>(m_obj);
249  }
250 
251 
252 private:
255  volatile_type m_obj;
256 };
257 
258 
259 
270 template<typename T_type, typename T_mutex>
271 struct lockable<T_type*, T_mutex>: public lockable<void*, T_mutex>
272 {
273  typedef lockable<void*, T_mutex> parent_type;
274  typedef T_type* acquired_type;
275  typedef lockable<acquired_type, mutex_type> type;
276  typedef typename volatile_trait<acquired_type>::add volatile_type;
277  typedef typename std::tr1::add_reference<typename volatile_trait<acquired_type>::remove>::type reference_type;
278  typedef typename std::tr1::add_reference<typename volatile_trait<acquired_type>::add>::type volatile_reference_type;
279  typedef typename std::tr1::add_reference<typename std::tr1::add_const<acquired_type>::type>::type take_type;
280 
281 
286  lockable(take_type _a_value = 0):
287  parent_type((void*&) _a_value)
288  {}
289 
295  volatile_reference_type access_volatile()
296  {
297  return (volatile_reference_type) parent_type::access_volatile();
298  }
299 
302  reference_type access_acquiree()
303  {
304  return (reference_type) parent_type::access_acquiree();
305  }
306 };
307 #endif
308 
309 
310 
311 // @addtogroup threadsafety
315 } // namespace sigx
316 
317 
318 #endif // end file guard
mutex_type m_mutex
Definition: lockable.h:69
T_mutex mutex_type
Definition: lockable.h:53
safe_lockable(toplevel_const_reference_type _a_value)
Constructs a lockable initializing T_type with _a_value.
Definition: lockable.h:129
safe_lockable< T_type, T_mutex > parent_type
Definition: lockable.h:179
T_type acquired_type
Definition: lockable.h:98
lockable(toplevel_const_reference_type _a_value)
Constructs a lockable initializing T_type with _a_value.
Definition: lockable.h:193
lockable_base< T_mutex > parent_type
Definition: lockable.h:96
std::tr1::add_reference< volatile_type >::type volatile_reference_type
Definition: lockable.h:107
std::tr1::add_reference< typename volatile_trait< acquired_type >::remove >::type reference_type
Definition: lockable.h:104
volatile_trait< acquired_type >::add volatile_type
Definition: lockable.h:101
Makes T_type lockable.
Definition: lockable.h:91
Traits for adding/removing the volatile qualifier from a type.
Definition: volatile_trait.h:40
volatile_reference_type access_volatile()
Definition: lockable.h:138
std::tr1::add_reference< typename const_trait< volatile_type >::add >::type cv_reference_type
Definition: lockable.h:113
std::tr1::add_reference< typename std::tr1::add_const< acquired_type >::type >::type toplevel_const_reference_type
Definition: lockable.h:115
Refinement of safe_lockable, open access to mutex and locked type.
Definition: lockable.h:177
The base for all lockables, template specialized for a specific lock, e.g. a boost::mutex.
Definition: lockable.h:51
lockable()
Default constructor.
Definition: lockable.h:187
Definition: auto_dispatchable.h:27
reference_type access_nonvolatile()
Definition: lockable.h:145
const_reference_type access_nonvolatile() const
Definition: lockable.h:160
mutex_type & mutex() const
Definition: lockable.h:56
lockable_base()
Definition: lockable.h:62
std::tr1::add_reference< typename const_trait< reference_type >::add >::type const_reference_type
Definition: lockable.h:110
cv_reference_type access_volatile() const
Definition: lockable.h:153
parent_type::toplevel_const_reference_type toplevel_const_reference_type
Definition: lockable.h:180
safe_lockable()
Default constructor.
Definition: lockable.h:122
volatile acquired_type add
Definition: volatile_trait.h:42
Private copy constructor and copy assignment ensure derived classes cannot be copied.
Definition: noncopyable.h:37
Locks the given mutex and ensures threadsafe write access to the given locked type.
Definition: lock_acquirer.h:88