OpendTect-6_4  6.4
refcount.h
Go to the documentation of this file.
1 #ifndef refcount_h
2 #define refcount_h
3 
4 /*+
5 ________________________________________________________________________
6 
7  (C) dGB Beheer B.V.; (LICENSE) http://opendtect.org/OpendTect_license.txt
8  Author: K. Tingdahl
9  Date: 13-11-2003
10  Contents: Basic functionality for reference counting
11  RCS: $Id$
12 ________________________________________________________________________
13 
14 -*/
15 
16 #include "atomic.h"
17 #include "objectset.h"
18 
19 
20 #define mInvalidRefCount (-1)
21 
22 
121 #define mRefCountImplWithDestructor(ClassName, DestructorImpl, delfunc ) \
123 public: \
124  void ref() const \
125  { \
126  refcount_.ref(); \
127  refNotify(); \
128  } \
129  bool refIfReffed() const \
130  { \
131  if ( !refcount_.refIfReffed() ) \
132  return false; \
133  \
134  refNotify(); \
135  return true; \
136  } \
137  void unRef() const \
138  { \
139  unRefNotify(); \
140  if ( refcount_.unRef() ) \
141  delfunc; \
142  return; \
143  } \
144  \
145  void unRefNoDelete() const \
146  { \
147  unRefNoDeleteNotify(); \
148  refcount_.unRefDontInvalidate(); \
149  } \
150  int nrRefs() const { return refcount_.count(); } \
151 private: \
152  virtual void refNotify() const {} \
153  virtual void unRefNotify() const {} \
154  virtual void unRefNoDeleteNotify() const {} \
155  mutable ReferenceCounter refcount_; \
156 protected: \
157  DestructorImpl; \
158 private:
159 
161 
163 #define mRefCountImpl(ClassName) \
164 mRefCountImplWithDestructor(ClassName, virtual ~ClassName(), delete this; );
165 
167 #define mRefCountImplNoDestructor(ClassName) \
168 mRefCountImplWithDestructor(ClassName, virtual ~ClassName() {}, delete this; );
169 
171 template <class T> inline
172 void unRefAndZeroPtr( T*& ptr )
173 {
174  if ( !ptr ) return;
175  ptr->unRef();
176  ptr = 0;
177 }
178 
179 
181 template <class T> inline
182 void unRefPtr( const T* ptr )
183 {
184  if ( !ptr ) return;
185  ptr->unRef();
186 }
187 
188 
190 template <class T> inline
191 void unRefNoDeletePtr( const T* ptr )
192 {
193  if ( !ptr ) return;
194  ptr->unRefNoDelete();
195 }
196 
197 
199 template <class T> inline
200 void refPtr( const T* ptr )
201 {
202  if ( !ptr ) return;
203  ptr->ref();
204 }
205 
206 mObjectSetApplyToAllFunc( deepUnRef, unRefPtr( os[idx] ), os.plainErase() )
208  os.plainErase() )
210 
211 
216 {
217 public:
218  inline void ref();
219  inline bool unRef();
223  inline void unRefDontInvalidate();
225 
226  od_int32 count() const { return count_.get(); }
227  inline bool refIfReffed();
229 
230 private:
231 
233 };
234 
235 
236 #ifdef __win__
237 # define mDeclareCounters od_int32 oldcount = count_.get(), newcount = 0
238 #else
239 # define mDeclareCounters od_int32 oldcount = count_.get(), newcount;
240 #endif
241 
243 {
245 
246  do
247  {
248  if ( oldcount==mInvalidRefCount )
249  {
250  pErrMsg("Invalid ref");
251 #ifdef __debug__
252  DBG::forceCrash(false);
253  newcount = 0; //To fool unitialized code warning
254 #else
255  newcount = 1; //Hoping for the best
256 #endif
257  }
258  else
259  {
260  newcount = oldcount+1;
261  }
262 
263  } while ( !count_.setIfValueIs( oldcount, newcount, &oldcount ) );
264 }
265 
266 
268 {
270 
271  do
272  {
273  if ( oldcount==mInvalidRefCount )
274  {
275  pErrMsg("Invalid reference.");
276 #ifdef __debug__
277  DBG::forceCrash(false);
278  newcount = 0; //To fool unitialized code warning
279 #else
280  return false;
281 #endif
282  }
283  else if ( oldcount==1 )
284  newcount = mInvalidRefCount;
285  else
286  newcount = oldcount-1;
287 
288  } while ( !count_.setIfValueIs(oldcount,newcount, &oldcount ) );
289 
290  return newcount==mInvalidRefCount;
291 }
292 
293 
295 {
297 
298  do
299  {
300  if ( oldcount==mInvalidRefCount )
301  {
302  pErrMsg("Invalid ref");
303 #ifdef __debug__
304  DBG::forceCrash(false);
305 #else
306  return false; //Hoping for the best
307 #endif
308  }
309  else if ( !oldcount )
310  return false;
311 
312  newcount = oldcount+1;
313 
314  } while ( !count_.setIfValueIs( oldcount, newcount, &oldcount ) );
315 
316  return true;
317 }
318 
319 
321 {
323 
324  do
325  {
326  if ( oldcount==mInvalidRefCount )
327  {
328  pErrMsg("Invalid reference.");
329 #ifdef __debug__
330  DBG::forceCrash(false);
331  newcount = 0; //Fool the unitialized warning
332 #else
333  newcount = 0; //Hope for the best
334 #endif
335  }
336  else
337  newcount = oldcount-1;
338 
339  } while ( !count_.setIfValueIs( oldcount, newcount, &oldcount ) );
340 }
341 
342 #undef mDeclareCounters
343 
344 
345 #endif
bool setIfValueIs(T curval, T newval, T *actualvalptr)
Definition: atomic.h:398
Definition: refcount.h:215
void deepUnRefNoDelete(ObjectSet< T > &os)
Definition: refcount.h:208
void ref()
Definition: refcount.h:242
void unRefPtr(const T *ptr)
Definition: refcount.h:182
void unRefNoDeletePtr(const T *ptr)
Definition: refcount.h:191
#define mDeclareCounters
Definition: refcount.h:239
bool refIfReffed()
Don&#39;t use in production, for debugging.
Definition: refcount.h:294
void refPtr(const T *ptr)
Reference class pointer. Works for null pointers.
Definition: refcount.h:200
#define od_int32
Definition: plftypes.h:31
int count() const
Definition: refcount.h:226
#define mInvalidRefCount
Definition: refcount.h:20
void forceCrash(bool withdump)
#define mObjectSetApplyToAllFunc(fn, op, extra)
Definition: objectset.h:108
void deepUnRef(ObjectSet< T > &os)
Definition: refcount.h:206
Definition: atomic.h:33
#define mClass(module)
Definition: commondefs.h:164
void deepRef(ObjectSet< T > &os)
Definition: refcount.h:209
#define pErrMsg(msg)
Definition: errmsg.h:60
void unRefDontInvalidate()
Will allow it to go to zero.
Definition: refcount.h:320
bool unRef()
Definition: refcount.h:267
Threads::Atomic< int > count_
Definition: refcount.h:232
void unRefAndZeroPtr(T *&ptr)
Un-reference class pointer, and set it to zero. Works for null-pointers.
Definition: refcount.h:172

Generated at for the OpendTect seismic interpretation project. Copyright (C): dGB Beheer B. V. 2019