ThreadingPolicies.h
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib 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 Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/common/ThreadingPolicies.h
22 
23  \brief Threading policies that can be applied to TerraLib classes that need some synchronization schema.
24 
25  \ingroup common
26 */
27 
28 #ifndef __TERRALIB_COMMON_INTERNAL_THREADINGPOLICIES_H
29 #define __TERRALIB_COMMON_INTERNAL_THREADINGPOLICIES_H
30 
31 // BOOST
32 #include <boost/noncopyable.hpp>
33 #include <boost/thread.hpp>
34 
35 #define TE_SINGLETHREADING 1
36 #define TE_MULTITHREADING 2
37 
38 //#define TE_THREADING_POLICIES TE_SINGLETHREADING
39 
40 #ifndef TE_THREADING_POLICIES
41  #define TE_THREADING_POLICIES TE_MULTITHREADING
42 #endif
43 
44 #if !defined TE_DEFAULT_MUTEX_POLICY
45  #define TE_DEFAULT_MUTEX_POLICY ::boost::mutex
46 #endif
47 
48 #if !defined TE_DEFAULT_LOCK_READING_POLICY
49  #define TE_DEFAULT_LOCK_READING_POLICY ::boost::lock_guard<TE_DEFAULT_MUTEX_POLICY>
50 #endif
51 
52 #if !defined TE_DEFAULT_LOCK_WRITING_POLICY
53  #define TE_DEFAULT_LOCK_WRITING_POLICY ::boost::lock_guard<TE_DEFAULT_MUTEX_POLICY>
54 #endif
55 
56 namespace te
57 {
58  namespace common
59  {
60  /*!
61  \class NonLockable
62 
63  \brief This policy doesn't actually perform a lock.
64 
65  Requirements on types:
66  <ul>
67  <li>NONE. </li>
68  </ul>
69  */
70  template<class Host,
71  class MutexPolicy = void,
72  class LockReadingPolicy = void,
73  class LockWritingPolicy = void> class NonLockable
74  {
75  public:
76 
77  typedef MutexPolicy MutexPolicyType;
78  typedef LockReadingPolicy LockReadingPolicyType;
79  typedef LockWritingPolicy LockWritingPolicyType;
80 
81  /*!
82  \class NonLockingPolicy
83 
84  \brief This class doesn't truelly acquire a lock over the host object/class.
85 
86  Requirements on LockingPolicy type:
87  <ul>
88  <li>NONE</li>
89  </ul>
90  */
91  template<class LockingPolicy> class NonLockingPolicy
92  {
93  public:
94 
95  /*! \brief Constructor to keep the semantics of class-level lock. */
96  explicit NonLockingPolicy()
97  {
98  }
99 
100  /*!
101  \brief Constructor.
102 
103  \param host The host object that uses the lock semantics.
104  */
105  explicit NonLockingPolicy(const Host&)
106  {
107  }
108 
109  /*!
110  \brief Constructor.
111 
112  \param host A pointer to the host object that uses the lock semantics.
113  */
114  explicit NonLockingPolicy(const Host*)
115  {
116  }
117 
118  /*! \brief Destructor. */
120  {
121  }
122 
123  private:
124 
127  };
128 
129  typedef volatile Host VolatileType;
132  };
133 
134 #if TE_THREADING_POLICIES == TE_MULTITHREADING
135 
136  /*!
137  \class ObjectLevelLockable
138 
139  \brief This policy assures an object-level locking scheme for a derived class.
140 
141  Requirements on types:
142  <ul>
143  <li>Host: is the type of the derived class from this policy. </li>
144  <li>MutexPolicy: any type that have a lock and unlock method. When using boost it can be one of the follwoing: boost::mutex, bost::timed_mutex, bost::recursive_mutex, boost::recursive_timed_mutex or boost::shared_mutex.</li>
145  <li>The LockReadingPolicy and LockWritingPolicy may be: boost::lock_guard, boost::unique_lock, boost::shared_lock, boost::upgrade_lock, boost::upgrade_to_unique_lock</li>
146  </ul>
147  */
148  template<class Host,
149  class MutexPolicy = TE_DEFAULT_MUTEX_POLICY,
150  class LockReadingPolicy = TE_DEFAULT_LOCK_READING_POLICY,
151  class LockWritingPolicy = TE_DEFAULT_LOCK_WRITING_POLICY> class ObjectLevelLockable
152  {
153  public:
154 
155  /*!
156  \class ObjectLevelLockingPolicy
157 
158  \brief This class acquires a lock over the host object.
159 
160  Requirements on type LockingPolicy:
161  <ul>
162  <li>it must be one of: boost::lock_guard, boost::unique_lock, boost::shared_lock, boost::upgrade_lock, boost::upgrade_to_unique_lock</li>
163  </ul>
164  */
165  template<class LockingPolicy> class ObjectLevelLockingPolicy
166  {
167  public:
168 
169  /*!
170  \brief Through this constructor the host object will be locked.
171 
172  \param host The host object to be locked.
173  */
174  explicit ObjectLevelLockingPolicy(const Host& host)
175  : m_lock(host.m_mtx)
176  {
177  }
178 
179  /*!
180  \brief Through this constructor the pointed host object will be locked.
181 
182  \param host A pointer to the host object to be locked.
183  */
184  explicit ObjectLevelLockingPolicy(const Host* host)
185  : m_lock(host->m_mtx)
186  {
187  }
188 
189  /*! \brief Destructor. */
191  {
192  }
193 
194  private:
195 
198 
199  private:
200 
201  LockingPolicy m_lock; //!< lock policy.
202  };
203 
204  typedef volatile Host VolatileType;
207 
208  friend class ObjectLevelLockingPolicy<LockReadingPolicy>;
209  friend class ObjectLevelLockingPolicy<LockWritingPolicy>;
210 
211  protected:
212 
213  /*! \brief Default constructor. */
215  : m_mtx()
216  {
217  }
218 
219  /*! \brief Copy constructor. */
221  : m_mtx()
222  {
223  }
224 
225  /*! \brief Destructor. */
227  {
228  }
229 
230  private:
231 
232  mutable MutexPolicy m_mtx; //!< The mutex used to control the object lock.
233  };
234 
235  /*!
236  \class ClassLevelLockable
237 
238  \brief This policy assures a class-level locking scheme for a derived class.
239 
240  Requirements on types:
241  <ul>
242  <li>Host: is the type of the derived class from this policy. </li>
243  <li>MutexPolicy: any type that have a lock and unlock method. When using boost it can be one of the follwoing: boost::mutex, bost::timed_mutex, bost::recursive_mutex, boost::recursive_timed_mutex or boost::shared_mutex.</li>
244  <li>The LockReadingPolicy and LockWritingPolicy may be: boost::lock_guard, boost::unique_lock, boost::shared_lock, boost::upgrade_lock, boost::upgrade_to_unique_lock</li>
245  </ul>
246  */
247  template<class Host,
248  class MutexPolicy = TE_DEFAULT_MUTEX_POLICY,
249  class LockReadingPolicy = TE_DEFAULT_LOCK_READING_POLICY,
250  class LockWritingPolicy = TE_DEFAULT_LOCK_WRITING_POLICY> class ClassLevelLockable
251  {
252  public:
253 
254  /*!
255  \class ClassLevelLockingPolicy
256 
257  \brief This class acquires a lock over the object class.
258 
259  Requirements on type LockingPolicy:
260  <ul>
261  <li>it must be one of: boost::lock_guard, boost::unique_lock, boost::shared_lock, boost::upgrade_lock, boost::upgrade_to_unique_lock</li>
262  </ul>
263  */
264  template<class LockingPolicy> class ClassLevelLockingPolicy : public boost::noncopyable
265  {
266  public:
267 
268  /*! \brief Default constructor. */
270  : m_lock(Host::sm_mtx)
271  {
272  }
273 
274  /*! \brief Constructor to keep the semantics of object-level lock. */
275  explicit ClassLevelLockingPolicy(const Host& host)
276  : m_lock(Host::sm_mtx)
277  {
278  }
279 
280  /*! \brief Constructor to keep the semantics of object-level lock. */
281  explicit ClassLevelLockingPolicy(const Host* host)
282  : m_lock(Host::sm_mtx)
283  {
284  }
285 
286  /*! \brief Destructor. */
288  {
289  }
290 
291  private:
292 
295 
296  private:
297 
298  LockingPolicy m_lock; //!< lock policy.
299  };
300 
301  typedef volatile Host VolatileType;
304 
305  friend class ClassLevelLockingPolicy<LockReadingPolicy>;
306  friend class ClassLevelLockingPolicy<LockWritingPolicy>;
307 
308  private:
309 
310  static MutexPolicy sm_mtx; //!< The mutex used to control the class lock.
311  };
312 
313  template<class Host, class MutexPolicy, class LockReadingPolicy, class LockWritingPolicy> MutexPolicy ClassLevelLockable<Host, MutexPolicy, LockReadingPolicy, LockWritingPolicy>::sm_mtx;
314 
315 #else // TE_THREADING_POLICIES == TE_SINGLETHREADING
316  template<class Host,
317  class MutexPolicy = void,
318  class LockReadingPolicy = void,
319  class LockWritingPolicy = void> class ObjectLevelLockable : public NonLockable<ObjectLevelLockable<Host, MutexPolicy, LockReadingPolicy, LockWritingPolicy>, MutexPolicy, LockReadingPolicy, LockWritingPolicy>
320  {
321  };
322 
323  template<class Host,
324  class MutexPolicy = TE_DEFAULT_MUTEX_POLICY,
325  class LockReadingPolicy = TE_DEFAULT_LOCK_READING_POLICY,
326  class LockWritingPolicy = TE_DEFAULT_LOCK_WRITING_POLICY> class ClassLevelLockable : public NonLockable<ClassLevelLockable<Host, MutexPolicy, LockReadingPolicy, LockWritingPolicy>, MutexPolicy, LockReadingPolicy, LockWritingPolicy>
327  {
328  };
329 
330 #endif // TE_THREADING_POLICIES == TE_MULTITHREADING
331 
332  } // end namespace common
333 } // end namespace te
334 
335 #endif // __TERRALIB_COMMON_INTERNAL_THREADINGPOLICIES_H
This policy doesn't actually perform a lock.
friend class ObjectLevelLockingPolicy< LockWritingPolicy >
friend class ClassLevelLockingPolicy< LockWritingPolicy >
LockWritingPolicy LockWritingPolicyType
This class acquires a lock over the object class.
NonLockingPolicy()
Constructor to keep the semantics of class-level lock.
ClassLevelLockingPolicy< LockWritingPolicy > LockWrite
ClassLevelLockingPolicy< LockReadingPolicy > LockRead
ObjectLevelLockingPolicy & operator=(const ObjectLevelLockingPolicy &)
ObjectLevelLockable()
Default constructor.
ClassLevelLockingPolicy & operator=(const ClassLevelLockingPolicy &)
#define TE_DEFAULT_LOCK_READING_POLICY
This class acquires a lock over the host object.
LockReadingPolicy LockReadingPolicyType
NonLockingPolicy< LockReadingPolicy > LockRead
ClassLevelLockingPolicy(const Host &host)
Constructor to keep the semantics of object-level lock.
URI C++ Library.
friend class ClassLevelLockingPolicy< LockReadingPolicy >
ObjectLevelLockingPolicy(const Host *host)
Through this constructor the pointed host object will be locked.
This class doesn't truelly acquire a lock over the host object/class.
NonLockingPolicy< LockWritingPolicy > LockWrite
ObjectLevelLockable(const ObjectLevelLockable &)
Copy constructor.
ObjectLevelLockingPolicy< LockWritingPolicy > LockWrite
#define TE_DEFAULT_LOCK_WRITING_POLICY
NonLockingPolicy & operator=(const NonLockingPolicy &)
This policy assures a class-level locking scheme for a derived class.
#define TE_DEFAULT_MUTEX_POLICY
MutexPolicy m_mtx
The mutex used to control the object lock.
NonLockingPolicy(const Host &)
Constructor.
ClassLevelLockingPolicy(const Host *host)
Constructor to keep the semantics of object-level lock.
NonLockingPolicy(const Host *)
Constructor.
This policy assures an object-level locking scheme for a derived class.
ObjectLevelLockingPolicy(const Host &host)
Through this constructor the host object will be locked.
ObjectLevelLockingPolicy< LockReadingPolicy > LockRead
friend class ObjectLevelLockingPolicy< LockReadingPolicy >
static MutexPolicy sm_mtx
The mutex used to control the class lock.