00001
00002
00003
00004
00005
00006
00007
00021 #ifndef OSCL_REFCOUNTER_H_INCLUDED
00022 #define OSCL_REFCOUNTER_H_INCLUDED
00023
00024 #ifndef OSCL_ASSERT_H_INCLUDED
00025 #include "oscl_assert.h"
00026 #endif
00027
00028 #ifndef OSCL_DEFALLOC_H_INCLUDED
00029 #include "oscl_defalloc.h"
00030 #endif
00031
00035 class OsclRefCounter
00036 {
00037 public:
00041 virtual void addRef() = 0;
00042
00046 virtual void removeRef() = 0;
00047
00051 virtual uint32 getCount() = 0;
00052
00053 virtual ~OsclRefCounter() {}
00054 };
00055
00056
00061 class OsclRefCounterDA : public OsclRefCounter
00062 {
00063 public:
00064
00085 OsclRefCounterDA(OsclAny *p, OsclDestructDealloc *dealloc):
00086 ptr(p), deallocator(dealloc), refcnt(1)
00087 {
00088 OSCL_ASSERT(ptr != NULL && deallocator != NULL);
00089 }
00090
00095 virtual ~OsclRefCounterDA() {}
00096
00100 void addRef()
00101 {
00102 ++refcnt;
00103 }
00104
00108 void removeRef()
00109 {
00110 if (--refcnt == 0)
00111 {
00112 if (ptr == this)
00113 {
00114
00115 deallocator->destruct_and_dealloc(this);
00116 }
00117 else
00118 {
00119
00120 deallocator->destruct_and_dealloc(ptr);
00121 delete(this);
00122 }
00123 }
00124 }
00125
00129 uint32 getCount()
00130 {
00131 return refcnt;
00132 }
00133
00134 private:
00135 OsclRefCounterDA();
00136 OsclRefCounterDA(const OsclRefCounterDA& x);
00137 OsclRefCounterDA& operator=(const OsclRefCounterDA& x);
00138
00139 OsclAny *ptr;
00140 OsclDestructDealloc *deallocator;
00141 uint32 refcnt;
00142 };
00143
00144
00149 template<class DeallocType>
00150 class OsclRefCounterSA : public OsclRefCounter
00151 {
00152 public:
00169 OsclRefCounterSA(OsclAny *p) :
00170 ptr(p), refcnt(1)
00171 {
00172 OSCL_ASSERT(ptr != NULL);
00173 }
00174
00179 virtual ~OsclRefCounterSA() {}
00180
00184 void addRef()
00185 {
00186 ++refcnt;
00187 }
00188
00192 void removeRef()
00193 {
00194 if (--refcnt == 0)
00195 {
00196 if (ptr == this)
00197 {
00198
00199
00200 DeallocType deallocator;
00201 deallocator.destruct_and_dealloc(this);
00202 }
00203 else
00204 {
00205
00206
00207 DeallocType deallocator;
00208 deallocator.destruct_and_dealloc(ptr);
00209 delete(this);
00210 }
00211 }
00212 }
00213
00217 uint32 getCount()
00218 {
00219 return refcnt;
00220 }
00221
00222 private:
00223 OsclRefCounterSA();
00224 OsclRefCounterSA(const OsclRefCounterSA<DeallocType>& x);
00225 OsclRefCounterSA<DeallocType>& operator=(const OsclRefCounterSA<DeallocType>& x);
00226
00227 OsclAny *ptr;
00228 uint32 refcnt;
00229 };
00230
00235 template<class LockType>
00236 class OsclRefCounterMTDA : public OsclRefCounter
00237 {
00238 public:
00239
00260 OsclRefCounterMTDA(OsclAny *p, OsclDestructDealloc *dealloc) :
00261 ptr(p), deallocator(dealloc), refcnt(1)
00262 {
00263 OSCL_ASSERT(ptr != NULL && deallocator != NULL);
00264 }
00265
00270 virtual ~OsclRefCounterMTDA() {}
00271
00275 void addRef()
00276 {
00277 lock.Lock();
00278 ++refcnt;
00279 lock.Unlock();
00280 }
00281
00285 void removeRef()
00286 {
00287 lock.Lock();
00288 if (--refcnt == 0)
00289 {
00290 if (ptr == this)
00291 {
00292
00293
00294 deallocator->destruct_and_dealloc(this);
00295 }
00296 else
00297 {
00298
00299 deallocator->destruct_and_dealloc(ptr);
00300 delete(this);
00301 }
00302 }
00303 else
00304 {
00305 lock.Unlock();
00306 }
00307 }
00308
00312 uint32 getCount()
00313 {
00314 return refcnt;
00315 }
00316
00317 private:
00318 OsclRefCounterMTDA();
00319 OsclRefCounterMTDA(const OsclRefCounterMTDA<LockType>& x);
00320 OsclRefCounterMTDA<LockType>& operator=(const OsclRefCounterMTDA<LockType>& x);
00321
00322 OsclAny *ptr;
00323 OsclDestructDealloc *deallocator;
00324 LockType lock;
00325 uint32 refcnt;
00326 };
00327
00328
00333 template<class DeallocType, class LockType>
00334 class OsclRefCounterMTSA : public OsclRefCounter
00335 {
00336 public:
00353 OsclRefCounterMTSA(OsclAny *p) :
00354 ptr(p), refcnt(1)
00355 {
00356 OSCL_ASSERT(ptr != NULL);
00357 }
00358
00363 virtual ~OsclRefCounterMTSA() {}
00364
00368 void addRef()
00369 {
00370 lock.Lock();
00371 ++refcnt;
00372 lock.Unlock();
00373 }
00374
00378 void removeRef()
00379 {
00380 lock.Lock();
00381 if (--refcnt == 0)
00382 {
00383 if (ptr == this)
00384 {
00385
00386 DeallocType deallocator;
00387 deallocator.destruct_and_dealloc(this);
00388 }
00389 else
00390 {
00391
00392
00393 DeallocType deallocator;
00394 deallocator.destruct_and_dealloc(ptr);
00395 delete(this);
00396 }
00397 }
00398 else
00399 {
00400 lock.Unlock();
00401 }
00402 }
00403
00407 uint32 getCount()
00408 {
00409 return refcnt;
00410 }
00411
00412 private:
00413 OsclRefCounterMTSA();
00414 OsclRefCounterMTSA(const OsclRefCounterMTSA<DeallocType, LockType>& x);
00415 OsclRefCounterMTSA<DeallocType, LockType>& operator=(const OsclRefCounterMTSA<DeallocType, LockType>& x);
00416
00417 OsclAny *ptr;
00418 LockType lock;
00419 uint32 refcnt;
00420 };
00421
00426 template<class DefAlloc>
00427 class Oscl_DefAllocWithRefCounter: public OsclRefCounter, public DefAlloc
00428 {
00429 public:
00432 static Oscl_DefAllocWithRefCounter* New()
00433 {
00434 DefAlloc alloc;
00435 OsclAny* p = alloc.ALLOCATE(sizeof(Oscl_DefAllocWithRefCounter));
00436 return new(p) Oscl_DefAllocWithRefCounter();
00437 }
00438
00441 void Delete()
00442 {
00443 removeRef();
00444 }
00445
00446 void addRef()
00447 {
00448 refcount++;
00449 }
00450
00451 void removeRef()
00452 {
00453 --refcount;
00454 if (refcount == 0)
00455 DefAlloc::deallocate(this);
00456 }
00457
00458 uint32 getCount()
00459 {
00460 return refcount;
00461 }
00462
00463 private:
00464 Oscl_DefAllocWithRefCounter(): refcount(1)
00465 {}
00466 uint32 refcount;
00467 };
00468
00472 #endif