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
00059 int32 AcquireCount();
00060 int32 IncRefsCount();
00061
00062
00063
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