cartobase  5.1.2
mutexrcptr.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 
35 #ifndef CARTOBASE_SMART_MUTEXRCPTR_H
36 #define CARTOBASE_SMART_MUTEXRCPTR_H
37 
38 #include <cartobase/smart/rcptr.h>
39 #include <cartobase/thread/mutex.h>
40 
41 namespace carto
42 {
43 
44  class MutexedObject : public RCObject
45  {
46  public:
47 #ifndef CARTO_NO_THREAD
49 #else
50  // fake, null mutex
51  class Mutex
52  {
53  public:
54  enum Type { Recursive=2 };
55  Mutex( int = Recursive ) {}
56  void lock() {}
57  void unlock() {}
58  };
59 #endif
60 
61  MutexedObject();
62  MutexedObject( const MutexedObject & );
63  virtual ~MutexedObject();
65 
66  Mutex* mutex() const;
67 
68  private:
69  mutable Mutex *_mutex;
70  };
71 
72 
82  template <typename T>
83  class MutexRcPtr
84  {
85  public:
86  MutexRcPtr();
87  MutexRcPtr( T* ptr );
88  MutexRcPtr( MutexRcPtr<T> & ptr );
89  ~MutexRcPtr();
90 
91  void reset( T *p=0 );
92  T * get();
93  const T * get() const;
94  T * release();
96  T * operator -> ();
97  const T * operator -> () const;
98  T & operator * ();
99  const T & operator * () const;
100  bool operator < ( const MutexRcPtr<T> &other ) const;
101  bool operator == ( const MutexRcPtr< T > &other ) const;
102  bool operator != ( const MutexRcPtr< T > &other ) const;
103  int refCount() const;
104 
106  rc_ptr<T> rcptr();
108  void lock();
109  void unlock();
110 
111  private:
112  rc_ptr<T> _rcptr;
113  };
114 
115 
116  // ----------------
117 
119  : _mutex( new MutexedObject::Mutex( Mutex::Recursive ) )
120  {
121  }
122 
123 
125  : RCObject( other ), _mutex( new MutexedObject::Mutex( Mutex::Recursive ) )
126  {
127  }
128 
129 
130  inline MutexedObject &
132  {
133  if( this != &other )
134  {
135  RCObject::operator = ( other );
136  // _mutex stays distinct
137  }
138  return *this;
139  }
140 
141 
143  {
144  return _mutex;
145  }
146 
147  // -----------------
148 
149  template <typename T>
151  {
152  }
153 
154 
155  template <typename T>
156  inline MutexRcPtr<T>::MutexRcPtr( T* ptr )
157  {
158  if( ptr )
159  {
160  ptr->mutex()->lock();
161  _rcptr.reset( ptr );
162  ptr->mutex()->unlock();
163  }
164  }
165 
166 
167  template <typename T>
169  {
170  ptr.lock();
171  _rcptr = ptr._rcptr;
172  ptr.unlock();
173  }
174 
175 
176  template <typename T>
178  {
179  reset( 0 );
180  }
181 
182 
183  template <typename T>
184  inline void MutexRcPtr<T>::reset( T* ptr )
185  {
186  lock();
187  T *t = _rcptr.get();
188  if( t )
189  {
190  if( _rcptr.refCount() == 1 )
191  {
192  _rcptr.release();
193  t->mutex()->unlock();
194  delete t;
195  }
196  else
197  {
198  _rcptr.release();
199  t->mutex()->unlock();
200  }
201  }
202 
203  if( ptr )
204  {
205  ptr->mutex()->lock();
206  _rcptr.reset( ptr );
207  ptr->mutex()->unlock();
208  }
209  }
210 
211 
212  template <typename T>
213  inline T* MutexRcPtr<T>::get()
214  {
215  /* lock();
216  T *t = _rcptr.get();
217  unlock();
218  return t; */
219  return _rcptr.get();
220  }
221 
222 
223  template <typename T>
224  inline const T* MutexRcPtr<T>::get() const
225  {
226  /* lock();
227  T *t = _rcptr.get();
228  unlock();
229  return t; */
230  return _rcptr.get();
231  }
232 
233 
234  template <typename T>
236  {
237  lock();
238  T *t = _rcptr.get();
239  _rcptr.release();
240  if( t )
241  t->mutex()->unlock();
242  return t;
243  }
244 
245  template <typename T>
247  {
248  if( this == &other )
249  return *this;
250  reset( 0 );
251  other.lock();
252  _rcptr = other._rcptr;
253  other.unlock();
254  }
255 
256 
257  template <typename T>
259  {
260  return get();
261  }
262 
263 
264  template <typename T>
265  inline const T* MutexRcPtr<T>::operator -> () const
266  {
267  return get();
268  }
269 
270 
271  template <typename T>
273  {
274  return *get();
275  }
276 
277 
278  template <typename T>
279  inline const T & MutexRcPtr<T>::operator * () const
280  {
281  return *get();
282  }
283 
284 
285  template <typename T>
286  inline bool MutexRcPtr<T>::operator < ( const MutexRcPtr<T> &other ) const
287  {
288  return get() < other.get();
289  }
290 
291 
292  template <typename T>
293  inline bool MutexRcPtr<T>::operator == ( const MutexRcPtr<T> &other ) const
294  {
295  return get() == other.get();
296  }
297 
298 
299  template <typename T>
300  inline bool MutexRcPtr<T>::operator != ( const MutexRcPtr<T> &other ) const
301  {
302  return get() != other.get();
303  }
304 
305 
306  template <typename T>
307  inline int MutexRcPtr<T>::refCount() const
308  {
309  lock();
310  int x = _rcptr.refCount();
311  unlock();
312  return x;
313  }
314 
315 
316  template <typename T>
318  {
319  return _rcptr;
320  }
321 
322 
323  template <typename T>
325  {
326  T *t = _rcptr.get();
327  return t ? t->mutex() : 0;
328  }
329 
330 
331  template <typename T>
332  inline void MutexRcPtr<T>::lock()
333  {
334  MutexedObject::Mutex *m = mutex();
335  if( m )
336  m->lock();
337  }
338 
339 
340  template <typename T>
341  inline void MutexRcPtr<T>::unlock()
342  {
343  MutexedObject::Mutex *m = mutex();
344  if( m )
345  m->unlock();
346  }
347 
348 }
349 
350 #endif
351 
Mutex-protected rc_ptr.
Definition: mutexrcptr.h:84
bool operator==(const MutexRcPtr< T > &other) const
Definition: mutexrcptr.h:293
MutexedObject::Mutex * mutex()
Definition: mutexrcptr.h:324
bool operator<(const MutexRcPtr< T > &other) const
Definition: mutexrcptr.h:286
bool operator!=(const MutexRcPtr< T > &other) const
Definition: mutexrcptr.h:300
rc_ptr< T > rcptr()
not thread-safe, almost private, for low-level operation only
Definition: mutexrcptr.h:317
MutexRcPtr< T > & operator=(MutexRcPtr< T > &other)
Definition: mutexrcptr.h:246
int refCount() const
Definition: mutexrcptr.h:307
void reset(T *p=0)
Definition: mutexrcptr.h:184
@ Recursive
Definition: mutex.h:54
Mutex(int x=Fast)
carto::Mutex Mutex
Definition: mutexrcptr.h:48
MutexedObject & operator=(const MutexedObject &)
Definition: mutexrcptr.h:131
Mutex * mutex() const
Definition: mutexrcptr.h:142
virtual ~MutexedObject()
Base class for reference counted objects (intrusive)
Definition: rcptr.h:110
RCObject & operator=(const RCObject &)
Definition: rcptr.h:140
Reference-counting pointer.
Definition: rcptr.h:640