00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef REF_H_HAS_BEEN_INCLUDED
00024 #define REF_H_HAS_BEEN_INCLUDED
00025
00026 #include <assert.h>
00027 #include "std/config.H"
00028 #include "std/thread_mutex.H"
00029 #ifdef _AIX
00030 #include <sys/atomic_op.h>
00031 #endif
00032 #ifdef sgi
00033 #include <limits.h>
00034 #include <mutex.h>
00035 #endif
00036
00037
00038 #ifdef Free
00039 #undef Free
00040 #endif
00041
00042 #define REF_CLASS(FOO) FOO; typedef REFptr<FOO> FOO##ptr; class FOO
00043 #define FD_REF_CLASS(FOO) FOO; typedef REFptr<FOO> FOO##ptr
00044
00045 #define cREFptr const REFptr
00046
00047 #define REF_ME(A) ((REFcounter *)A)
00048
00049
00050
00051
00052 class REFcounter {
00053 private:
00054 union {
00055 struct {
00056
00057
00058 #if defined(WIN32) || defined(i386)
00059 unsigned int _ref:31;
00060 unsigned int _lock:1;
00061 #else
00062 unsigned int _lock:1;
00063 unsigned int _ref:31;
00064 #endif
00065 } _a;
00066 unsigned int _all;
00067 } _u;
00068 ThreadMutex _mutex;
00069
00070 public:
00071 REFcounter() { _u._all = 0; }
00072 virtual ~REFcounter() { }
00073 void Own() const {
00074 #ifdef _AIX
00075 fetch_and_add((int *) &REF_ME(this)->_u._all, 1);
00076 #elif defined(sgi)
00077 test_then_add((unsigned long *) &REF_ME(this)->_u._all, 1);
00078 #else
00079 #ifdef USE_PTHREAD
00080 CriticalSection cs((ThreadMutex*)&_mutex);
00081 #endif
00082 REF_ME(this)->_u._a._ref++;
00083 #endif
00084 }
00085
00086
00087
00088 void Free() const {
00089
00090 #if defined(_AIX)
00091 if (fetch_and_add((int *) &REF_ME(this)->_u._all, -1) == 1)
00092 #elif defined(sgi)
00093
00094 if (test_then_add((unsigned long *) &REF_ME(this)->_u._all, UINT_MAX)==1)
00095 #else
00096 #ifdef USE_PTHREAD
00097 CriticalSection cs((ThreadMutex*)&_mutex);
00098 #endif
00099 if (--REF_ME(this)->_u._all == 0)
00100 #endif
00101 {
00102 #if !defined(_AIX) && !defined(sgi)
00103 ((ThreadMutex*)&_mutex)->unlock();
00104 #endif
00105 REF_ME(this)->Lock();
00106 #if !defined(_AIX) && !defined(sgi)
00107 ((ThreadMutex*)&_mutex)->lock();
00108 #endif
00109 delete REF_ME(this);
00110 }
00111 }
00112 int Lock() { CriticalSection cs(&_mutex);
00113 int old = _u._a._lock; _u._a._lock = 1;
00114 return old; }
00115 void Unlock() { CriticalSection cs(&_mutex);
00116 _u._a._lock = 0; }
00117 int Unique() const { CriticalSection cs((ThreadMutex*)&_mutex);
00118 return _u._a._ref == 1; }
00119 };
00120
00121 class REFlock {
00122 REFcounter *_ref;
00123 int _old;
00124 public :
00125 REFlock(REFcounter *r):_ref(r) { _old = _ref->Lock(); }
00126 ~REFlock() { if (!_old) _ref->Unlock(); }
00127 };
00128
00129
00130
00131
00132
00133
00134 template <class T>
00135 class REFptr {
00136 protected:
00137 T * p_;
00138 public:
00139 REFptr( ): p_(0) { }
00140 REFptr(cREFptr<T> &p): p_(p.p_) { if (p_) REF_ME(p_)->Own (); }
00141 REFptr(T * pObj): p_(pObj) { if (p_) REF_ME(p_)->Own (); }
00142
00143
00144
00145 #if !defined(sun)
00146 virtual
00147 #endif
00148 ~REFptr() { if (p_) REF_ME(p_)->Free(); }
00149
00150 void Init () { p_ = 0; }
00151 void Clear () { if (p_) REF_ME(p_)->Free(); p_=0;}
00152
00153 REFptr<T> &operator = (T * o) { if (o != p_) {
00154 if (o) REF_ME(o)->Own();
00155 Clear();
00156 p_ = o;
00157 }
00158 return *this; }
00159 REFptr<T> &operator = (cREFptr<T>& p) { if (p.p_ != p_) {
00160 if (p.p_) REF_ME(p.p_)->Own();
00161 Clear();
00162 p_ = p.p_;
00163 }
00164 return *this; }
00165
00166 bool operator == (cREFptr<T>& p) const { return p.p_ == p_; }
00167 bool operator != (cREFptr<T>& p) const { return p.p_ != p_; }
00168
00169 int operator ! () const { return !p_; }
00170
00171 const T & operator * () const { assert(p_); return *p_; }
00172 T & operator * () { assert(p_); return *p_; }
00173 const T * operator -> () const { assert(p_); return p_; }
00174 T * operator -> () { assert(p_); return p_; }
00175
00176 operator int() const { return (int)p_;}
00177 T *pointer() const { return p_; }
00178 T *&pointer() { return p_; }
00179
00180 REFptr<T> &Cast_from_void(void *V) { *this = (T *) V; return *this; }
00181 friend ostream& operator<<(ostream& os,cREFptr<T>& p) { return os << p.p_; }
00182 };
00183
00184 #undef REF_ME
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 #define MAKE_PTR_BASEC(A) \
00197 class A; \
00198 class A##subc { \
00199 public : \
00200 virtual A *A##cast() const = 0; \
00201 }; \
00202 typedef const class A##ptr c##A##ptr; \
00203 class A##ptr : public REFptr<A>, public A##subc { \
00204 public : \
00205 A##ptr() { }\
00206 A##ptr(A *g): REFptr<A>(g) { }\
00207 A##ptr(const A##ptr &p): REFptr<A>(p.p_) { }\
00208 A##ptr(const A##subc &p): REFptr<A>(p.A##cast()) { } \
00209 \
00210 virtual A *A##cast() const { return p_; } \
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 #define MAKE_PTR_SUBC(A,B) \
00225 class A; \
00226 class A##subc: public B##subc { \
00227 public : \
00228 virtual A *A##cast() const = 0; \
00229 virtual B *B##cast() const { return (B *)A##cast(); } \
00230 }; \
00231 typedef const class A##ptr c##A##ptr; \
00232 class A##ptr : public REFptr<A>, public A##subc { \
00233 public : \
00234 A##ptr() { }\
00235 A##ptr(A *g): REFptr<A>(g) { }\
00236 A##ptr(const A##ptr &p): REFptr<A>(p.p_) { }\
00237 A##ptr(const A##subc &p): REFptr<A>(p.A##cast()) { } \
00238 \
00239 virtual A *A##cast() const { return p_; } \
00240 }
00241
00242 #endif // REF_H_HAS_BEEN_INCLUDED