00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef __REF_PTR_H__
00027 #define __REF_PTR_H__
00028
00029 #include <stdlib.h>
00030
00031 #ifdef USE_PTHREADS
00032 #include <pthread.h>
00033 #elif defined WIN32
00034 #include <winnt.h>
00035 #endif
00036
00064 namespace cbits
00065 {
00066
00085 template< typename T >
00086 class ref_ptr
00087 {
00088 public:
00089
00095 ref_ptr<T>( T* t ) : _t(t),_refs(new long)
00096 {
00097 *(_refs) = 1;
00098 #ifdef USE_PTHREADS
00099 _lock = new pthread_mutex_t;
00100 pthread_mutex_init( _lock, 0 );
00101 #elif defined WIN32
00102 _lock = CreateMutex( 0, FALSE, 0 );
00103 #endif
00104 }
00105
00106
00112 ref_ptr<T>( const ref_ptr<T>& r )
00113 {
00114 r.lock();
00115 _t = r._t;
00116 _refs = r._refs;
00117 _lock = r._lock;
00118 (*_refs)++;
00119 r.unlock();
00120 }
00121
00122
00128 ref_ptr<T>& operator=( const ref_ptr<T>& r )
00129 {
00130 if( _t == r._t )
00131 {
00132 return *this;
00133 }
00134
00135 r.lock();
00136 (*r._refs)++;
00137
00138 lock();
00139 (*_refs)--;
00140 int n = *_refs;
00141 unlock();
00142
00143 if( 0 == n )
00144 {
00145 freeObject();
00146 }
00147
00148 _t = r._t;
00149 _refs = r._refs;
00150 _lock = r._lock;
00151 r.unlock();
00152 return *this;
00153 }
00154
00155
00164 const long getRefCount() const
00165 {
00166 lock();
00167 long n = *_refs;
00168 unlock();
00169 return n;
00170 }
00171
00172
00178 bool operator==( const ref_ptr<T>& r )
00179 {
00180 return _t == r._t;
00181 }
00182
00183
00189 T* operator->()
00190 {
00191 return _t;
00192 }
00193
00194
00200 T& operator*()
00201 {
00202 return *_t;
00203 }
00204
00205
00213 virtual ~ref_ptr<T>()
00214 {
00215 lock();
00216 (*_refs)--;
00217 int n = *_refs;
00218 unlock();
00219
00220 if( 0 == n )
00221 {
00222 freeObject();
00223 }
00224 }
00225
00226
00227 protected:
00228
00229 T* _t;
00230 long* _refs;
00232 private:
00233
00238 void freeObject()
00239 {
00240 delete _t;
00241 delete _refs;
00242 #if defined USE_PTHREADS
00243 delete _lock;
00244 #elif defined WIN32
00245 CloseHandle( _lock );
00246 #endif
00247 }
00248
00252 void lock() const
00253 {
00254 #ifdef USE_PTHREADS
00255 pthread_mutex_lock( _lock );
00256 #elif defined(WIN32)
00257 WaitForSingleObject( _lock, INFINITE );
00258 #endif
00259
00260 }
00261
00265 void unlock() const
00266 {
00267 #ifdef USE_PTHREADS
00268 pthread_mutex_unlock( _lock );
00269 #elif defined(WIN32)
00270 ReleaseMutex( _lock );
00271 #endif
00272 }
00273
00274 #ifdef USE_PTHREADS
00275 mutable pthread_mutex_t * _lock;
00276 #elif defined(WIN32)
00277 HANDLE _lock;
00278 #endif
00279 };
00280
00281 };
00282
00283 #endif
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308