cartobase  5.0.5
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  T * release();
95  T * operator -> ();
96  T & operator * ();
97  bool operator < ( const MutexRcPtr<T> &other ) const;
98  bool operator == ( const MutexRcPtr< T > &other ) const;
99  bool operator != ( const MutexRcPtr< T > &other ) const;
100  int refCount() const;
101 
103  rc_ptr<T> rcptr();
105  void lock();
106  void unlock();
107 
108  private:
109  rc_ptr<T> _rcptr;
110  };
111 
112 
113  // ----------------
114 
116  : _mutex( new MutexedObject::Mutex( Mutex::Recursive ) )
117  {
118  }
119 
120 
122  : RCObject( other ), _mutex( new MutexedObject::Mutex( Mutex::Recursive ) )
123  {
124  }
125 
126 
127  inline MutexedObject &
129  {
130  if( this != &other )
131  {
132  RCObject::operator = ( other );
133  // _mutex stays distinct
134  }
135  return *this;
136  }
137 
138 
140  {
141  return _mutex;
142  }
143 
144  // -----------------
145 
146  template <typename T>
148  {
149  }
150 
151 
152  template <typename T>
153  inline MutexRcPtr<T>::MutexRcPtr( T* ptr )
154  {
155  if( ptr )
156  {
157  ptr->mutex()->lock();
158  _rcptr.reset( ptr );
159  ptr->mutex()->unlock();
160  }
161  }
162 
163 
164  template <typename T>
166  {
167  ptr.lock();
168  _rcptr = ptr._rcptr;
169  ptr.unlock();
170  }
171 
172 
173  template <typename T>
175  {
176  reset( 0 );
177  }
178 
179 
180  template <typename T>
181  inline void MutexRcPtr<T>::reset( T* ptr )
182  {
183  lock();
184  T *t = _rcptr.get();
185  if( t )
186  {
187  if( _rcptr.refCount() == 1 )
188  {
189  _rcptr.release();
190  t->mutex()->unlock();
191  delete t;
192  }
193  else
194  {
195  _rcptr.release();
196  t->mutex()->unlock();
197  }
198  }
199 
200  if( ptr )
201  {
202  ptr->mutex()->lock();
203  _rcptr.reset( ptr );
204  ptr->mutex()->unlock();
205  }
206  }
207 
208 
209  template <typename T>
210  inline T* MutexRcPtr<T>::get()
211  {
212  /* lock();
213  T *t = _rcptr.get();
214  unlock();
215  return t; */
216  return _rcptr.get();
217  }
218 
219 
220  template <typename T>
222  {
223  lock();
224  T *t = _rcptr.get();
225  _rcptr.release();
226  if( t )
227  t->mutex()->unlock();
228  return t;
229  }
230 
231  template <typename T>
233  {
234  if( this == &other )
235  return *this;
236  reset( 0 );
237  other.lock();
238  _rcptr = other._rcptr;
239  other.unlock();
240  }
241 
242 
243  template <typename T>
245  {
246  return get();
247  }
248 
249 
250  template <typename T>
252  {
253  return *get();
254  }
255 
256 
257  template <typename T>
258  inline bool MutexRcPtr<T>::operator < ( const MutexRcPtr<T> &other ) const
259  {
260  return get() < other.get();
261  }
262 
263 
264  template <typename T>
265  inline bool MutexRcPtr<T>::operator == ( const MutexRcPtr<T> &other ) const
266  {
267  return get() == other.get();
268  }
269 
270 
271  template <typename T>
272  inline bool MutexRcPtr<T>::operator != ( const MutexRcPtr<T> &other ) const
273  {
274  return get() != other.get();
275  }
276 
277 
278  template <typename T>
279  inline int MutexRcPtr<T>::refCount() const
280  {
281  lock();
282  int x = _rcptr.refCount();
283  unlock();
284  return x;
285  }
286 
287 
288  template <typename T>
290  {
291  return _rcptr;
292  }
293 
294 
295  template <typename T>
297  {
298  T *t = _rcptr.get();
299  return t ? t->mutex() : 0;
300  }
301 
302 
303  template <typename T>
304  inline void MutexRcPtr<T>::lock()
305  {
307  if( m )
308  m->lock();
309  }
310 
311 
312  template <typename T>
313  inline void MutexRcPtr<T>::unlock()
314  {
316  if( m )
317  m->unlock();
318  }
319 
320 }
321 
322 #endif
323 
MutexRcPtr< T > & operator=(MutexRcPtr< T > &other)
Definition: mutexrcptr.h:232
Base class for reference counted objects (intrusive)
Definition: rcptr.h:106
int refCount() const
Definition: mutexrcptr.h:279
RCObject & operator=(const RCObject &)
Definition: rcptr.h:140
carto::Mutex Mutex
Definition: mutexrcptr.h:48
bool operator==(const carto::block< T, N > &b1, const carto::block< T, N > &b2)
Definition: block.h:252
VoxelRGB operator*(const VoxelRGB &aa, const uint8_t &bb)
Definition: voxelrgb_def.h:637
Mutex * mutex() const
Definition: mutexrcptr.h:139
bool operator<(const MutexRcPtr< T > &other) const
Definition: mutexrcptr.h:258
Reference-counting pointer.
Definition: rcptr.h:639
bool operator!=(const MutexRcPtr< T > &other) const
Definition: mutexrcptr.h:272
rc_ptr< T > rcptr()
not thread-safe, almost private, for low-level operation only
Definition: mutexrcptr.h:289
virtual ~MutexedObject()
Mutex(int x=Fast)
MutexedObject & operator=(const MutexedObject &)
Definition: mutexrcptr.h:128
bool operator==(const MutexRcPtr< T > &other) const
Definition: mutexrcptr.h:265
Mutex-protected rc_ptr.
Definition: mutexrcptr.h:83
MutexedObject::Mutex * mutex()
Definition: mutexrcptr.h:296
void reset(T *p=0)
Definition: mutexrcptr.h:181