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