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