Atom.h

Go to the documentation of this file.
00001 
00002 #ifndef _ATOM_H
00003 #define _ATOM_H
00004 
00005 #include <Gehnaphore.h>
00006 #include <SupportDefs.h>
00007 
00008 namespace std {
00009 class type_info;
00010 }
00011 class BDataIO;
00012 
00013 enum {
00014     B_ATOM_REPORT_REMOVE_HEADER     = 0x0001
00015 };
00016 
00017 class BAtom
00018 {
00019 
00020     private:
00021 
00022                 int32   m_primary;
00023                 int32   m_secondary;
00024 
00025         virtual void    _delete();
00026 
00027     protected:
00028 
00029         virtual void    Cleanup();
00030         virtual void    Acquired();
00031 
00032                         BAtom();
00033         virtual         ~BAtom();
00034 
00035     public:
00036                 void    Report(BDataIO& io, const char* prefix="  ", uint32 flags=0) const;
00037                 void    Report(const char* prefix="  ", uint32 flags=0) const;
00038                 
00039         static  int32   MarkLeakReport();
00040         static  void    LeakReport(BDataIO& io, int32 mark=0, int32 last=-1);
00041         static  void    LeakReport(int32 mark=0, int32 last=-1);
00042         
00043         static  bool    ExistsAndAcquire(BAtom* atom);
00044         static  bool    ExistsAndIncRefs(BAtom* atom);
00045         
00046         static  void    StartWatching(const std::type_info* type);
00047         static  void    StopWatching(const std::type_info* type);
00048 
00049         const BAtom &   operator =(const BAtom &p) { return p; };
00050 
00051                 int32   Acquire(void *id = NULL);
00052                 int32   Release(void *id = NULL);
00053                 int32   IncRefs(void *id = NULL);
00054                 int32   DecRefs(void *id = NULL);
00055                 
00056                 bool    AttemptAcquire(void *id = NULL);
00057                 
00058                 // For debugging ONLY!
00059                 int32   AcquireCount();
00060                 int32   IncRefsCount();
00061                 
00062                 // Return true if Cleanup() has been (or is about
00063                 // to be) called.
00064                 bool    CleanupCalled() const;
00065 };
00066 
00067 template <class TYPE> class atom;
00068 template <class TYPE> class atomref;
00069 
00070 template <class TYPE>
00071 class AtomPtr {
00072     private:
00073         TYPE *ptr;
00074         Gehnaphore lock;
00075         
00076         friend class atom<TYPE>;
00077         friend class atomref<TYPE>;
00078 
00079         TYPE * Acquire(void *id) {
00080             lock.Lock();
00081             TYPE *t = ptr;
00082             if (t) t->Acquire(id);
00083             lock.Unlock();
00084             return t;
00085         };
00086 
00087         TYPE * AcquireRef(void *id) {
00088             lock.Lock();
00089             TYPE *t = ptr;
00090             if (t) t->Acquire(id);
00091             lock.Unlock();
00092             return t;
00093         };
00094 
00095     public:
00096         AtomPtr() { ptr = NULL; };
00097         AtomPtr(TYPE *p) { ptr = p; ptr->Acquire(this); };
00098         ~AtomPtr() { if (ptr) ptr->Release(this); };
00099 
00100         atom<TYPE> Ptr() {
00101             atom<TYPE> a = *this;
00102             return a;
00103         }
00104 
00105         AtomPtr<TYPE> &operator =(AtomPtr<TYPE> &p) {
00106             TYPE *safe = NULL;
00107             p.lock.Lock();
00108             TYPE *t = p.ptr;
00109             if (t) t->Acquire(this);
00110             p.lock.Unlock();
00111             lock.Lock();
00112             if (ptr!=t) {
00113                 safe = ptr;
00114                 ptr = t;
00115             } else if (t)
00116                 safe = t;
00117             lock.Unlock();
00118             if (safe) safe->Release(this);
00119             return *this;
00120         };
00121 
00122         AtomPtr<TYPE> &operator =(TYPE *p) {
00123             TYPE *safe = NULL;
00124             lock.Lock();
00125             if (ptr!=p) {
00126                 safe = ptr;
00127                 ptr = p;
00128                 if (ptr) ptr->Acquire(this);
00129             };
00130             lock.Unlock();
00131             if (safe) safe->Release(this);
00132             return *this;
00133         };
00134 };
00135 
00136 template <class TYPE>
00137 class AtomRef {
00138     private:
00139         TYPE *ptr;
00140         Gehnaphore lock;
00141 
00142         friend class atom<TYPE>;
00143         friend class atomref<TYPE>;
00144 
00145         TYPE * AcquireRef(void *id) {
00146             lock.Lock();
00147             TYPE *t = ptr;
00148             if (t) t->IncRefs(id);
00149             lock.Unlock();
00150             return t;
00151         };
00152 
00153     public:
00154         AtomRef() { ptr = NULL; };
00155         AtomRef(TYPE *p) { ptr = p; ptr->IncRefs(this); };
00156         ~AtomRef() { if (ptr) ptr->DecRefs(this); };
00157 
00158         AtomRef<TYPE> &operator =(AtomRef<TYPE> &p) {
00159             TYPE *safe = NULL;
00160             p.lock.Lock();
00161             TYPE *t = p.ptr;
00162             if (t) t->IncRefs(this);
00163             p.lock.Unlock();
00164             lock.Lock();
00165             if (ptr!=t) {
00166                 safe = ptr;
00167                 ptr = t;
00168             } else if (t)
00169                 safe = t;
00170             lock.Unlock();
00171             if (safe) safe->DecRefs(this);
00172             return *this;
00173         };
00174 
00175         AtomRef<TYPE> &operator =(TYPE *p) {
00176             TYPE *safe = NULL;
00177             lock.Lock();
00178             if (ptr!=p) {
00179                 safe = ptr;
00180                 ptr = p;
00181                 if (ptr) ptr->IncRefs(this);
00182             };
00183             lock.Unlock();
00184             if (safe) safe->DecRefs(this);
00185             return *this;
00186         };
00187 };
00188 
00189 template <class TYPE>
00190 class atomref {
00191     private:
00192         TYPE *ptr;
00193     public:
00194         bool operator !=(void *p) { return ptr != p; };
00195         bool operator ==(const atomref<TYPE> &p) { return ptr == p.ptr; };
00196         operator TYPE*() const { return ptr; };
00197         operator atomref<BAtom>() const { return atomref(ptr); };
00198         TYPE * operator ->() const { return ptr; };
00199         const atomref<TYPE> &operator =(TYPE *p) {
00200             if (ptr!=p) {
00201                 if (p) p->IncRefs(this);
00202                 if (ptr) ptr->DecRefs(this);
00203                 ptr = p;
00204             };
00205             return *this;
00206         };
00207         const atomref<TYPE> &operator =(const atom<TYPE> &p) {
00208             return ((*this) = (TYPE*)p);
00209         };
00210         const atomref<TYPE> &operator =(const atomref<TYPE> &p) {
00211             return ((*this) = p.ptr);
00212         };
00213 
00214         const atomref<TYPE> &operator =(AtomPtr<TYPE> &p) {
00215             TYPE *t = p.AcquireRef(this);
00216             if (ptr) ptr->DecRefs(this);
00217             ptr = t;
00218             return *this;
00219         };
00220         const atomref<TYPE> &operator =(AtomRef<TYPE> &p) {
00221             TYPE *t = p.AcquireRef(this);
00222             if (ptr) ptr->DecRefs(this);
00223             ptr = t;
00224             return *this;
00225         };
00226 
00227         atomref() { ptr = NULL; };
00228         atomref(AtomPtr<TYPE> &p) { ptr = NULL; *this = p; };
00229         atomref(AtomRef<TYPE> &p) { ptr = NULL; *this = p; };
00230         atomref(const atom<TYPE> &p) { ptr = (TYPE*)p; if (ptr) ptr->IncRefs(this); };
00231         atomref(const atomref<TYPE> &p) { ptr = p.ptr; if (ptr) ptr->IncRefs(this); };
00232         atomref(TYPE *p) { ptr = p; if (ptr) ptr->IncRefs(this); };
00233         ~atomref() { if (ptr) ptr->DecRefs(this); };
00234 };
00235 
00236 template <class TYPE>
00237 class atom {
00238     private:
00239         TYPE *ptr;
00240     public:
00241         bool operator !=(int p) { return ((int)ptr) != p; };
00242         bool operator ==(int p) { return ((int)ptr) == p; };
00243         operator TYPE*() const { return ptr; };
00244         operator atom<BAtom>() const { return atom<BAtom>(ptr); };
00245         operator atomref<BAtom>() const { return atomref<BAtom>(ptr); };
00246         TYPE * operator ->() const { return ptr; };
00247         const atom<TYPE> &operator =(TYPE *p) {
00248             if (ptr!=p) {
00249                 if (p) p->Acquire(this);
00250                 if (ptr) ptr->Release(this);
00251                 ptr = p;
00252             };
00253             return *this;
00254         };
00255         const atom<TYPE> &operator =(const atom<TYPE> &p) {
00256             return ((*this) = p.ptr);
00257         };
00258         const atom<TYPE> &operator =(AtomPtr<TYPE> &p) {
00259             TYPE *t = p.Acquire(this);
00260             if (ptr) ptr->Release(this);
00261             ptr = t;
00262             return *this;
00263         };
00264 
00265         atom() { ptr = NULL; };
00266         atom(AtomPtr<TYPE> &p) { ptr = NULL; *this = p; };
00267         atom(const atom<TYPE> &p) { ptr = p.ptr; if (ptr) ptr->Acquire(this); };
00268         atom(TYPE *p) { ptr = p; if (ptr) ptr->Acquire(this); };
00269         ~atom() { if (ptr) ptr->Release(this); };
00270 };
00271 
00272 #endif

Copyright 2005 by yellowTAB GmbH, Be Inc., Palm Source Inc. and their respective legal successors
All rights reserved.