csutil/refcount.h
Go to the documentation of this file.00001 /* 00002 Crystal Space Reference Counting Interface 00003 Copyright (C) 2002 by Jorrit Tyberghein 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public 00016 License along with this library; if not, write to the Free 00017 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 */ 00019 00020 #ifndef __CS_REFCOUNT_H__ 00021 #define __CS_REFCOUNT_H__ 00022 00027 #include "csextern.h" 00028 #include "csutil/threading/atomicops.h" 00029 #include "csutil/reftrackeraccess.h" 00030 00038 class csRefCount 00039 { 00040 protected: 00041 int ref_count; 00042 00043 // To avoid a problem with MSVC and multiple DLLs (with separate memory 00044 // space) we have to use a virtual destructor. 00045 // @@@ Another alternative is to force this function to be non-inline, as 00046 // doing so will most likely achieve the same result. 00047 virtual void Delete () 00048 { 00049 delete this; 00050 } 00051 00052 virtual ~csRefCount () 00053 { 00054 csRefTrackerAccess::TrackDestruction (this, ref_count); 00055 } 00056 00057 public: 00059 00060 csRefCount () : ref_count (1) 00061 { 00062 csRefTrackerAccess::TrackConstruction (this); 00063 } 00064 csRefCount (const csRefCount& other) : ref_count (1) 00065 { 00066 csRefTrackerAccess::TrackConstruction (this); 00067 } 00069 00071 void IncRef () 00072 { 00073 csRefTrackerAccess::TrackIncRef (this, ref_count); 00074 ref_count++; 00075 } 00077 void DecRef () 00078 { 00079 csRefTrackerAccess::TrackDecRef (this, ref_count); 00080 ref_count--; 00081 if (ref_count <= 0) 00082 Delete (); 00083 } 00085 int GetRefCount () const { return ref_count; } 00086 }; 00087 00088 namespace CS 00089 { 00090 namespace Utility 00091 { 00107 template<typename ActualClass> 00108 class FastRefCount 00109 { 00110 protected: 00111 int ref_count; 00112 00113 ~FastRefCount () 00114 { 00115 csRefTrackerAccess::TrackDestruction (this, ref_count); 00116 } 00117 00118 public: 00120 00121 FastRefCount () : ref_count (1) 00122 { 00123 csRefTrackerAccess::TrackConstruction (this); 00124 } 00125 FastRefCount (const FastRefCount& other) : ref_count (1) 00126 { 00127 csRefTrackerAccess::TrackConstruction (this); 00128 } 00130 00132 void IncRef () 00133 { 00134 csRefTrackerAccess::TrackIncRef (this, ref_count); 00135 ref_count++; 00136 } 00138 void DecRef () 00139 { 00140 csRefTrackerAccess::TrackDecRef (this, ref_count); 00141 ref_count--; 00142 if (ref_count <= 0) 00143 delete static_cast<ActualClass*> (this); 00144 } 00146 int GetRefCount () const { return ref_count; } 00147 }; 00148 00155 class InternalRefCount 00156 { 00157 protected: 00158 int internal_ref_count; 00159 00160 // To be implemented as needed. 00161 virtual void InternalRemove() { return; } 00162 00163 virtual ~InternalRefCount () 00164 { 00165 csRefTrackerAccess::TrackDestruction (this, internal_ref_count); 00166 } 00167 00168 public: 00170 InternalRefCount () : internal_ref_count (0) 00171 { 00172 csRefTrackerAccess::TrackConstruction (this); 00173 } 00174 00176 void InternalIncRef() 00177 { 00178 csRefTrackerAccess::TrackIncRef (this, internal_ref_count); 00179 internal_ref_count++; 00180 } 00181 00183 void InternalDecRef () 00184 { 00185 csRefTrackerAccess::TrackDecRef (this, internal_ref_count); 00186 internal_ref_count--; 00187 if (internal_ref_count <= 0) 00188 { 00189 InternalRemove(); 00190 } 00191 } 00192 00194 int GetInternalRefCount () const { return internal_ref_count; } 00195 }; 00196 00203 class AtomicRefCount 00204 { 00205 protected: 00206 int32 ref_count; 00207 00208 // To avoid a problem with MSVC and multiple DLLs (with separate memory 00209 // space) we have to use a virtual destructor. 00210 // @@@ Another alternative is to force this function to be non-inline, as 00211 // doing so will most likely achieve the same result. 00212 virtual void Delete () 00213 { 00214 delete this; 00215 } 00216 00217 virtual ~AtomicRefCount () 00218 { 00219 csRefTrackerAccess::TrackDestruction (this, ref_count); 00220 } 00221 00222 public: 00224 00225 AtomicRefCount () : ref_count (1) 00226 { 00227 csRefTrackerAccess::TrackConstruction (this); 00228 } 00229 AtomicRefCount (const AtomicRefCount& other) : ref_count (1) 00230 { 00231 csRefTrackerAccess::TrackConstruction (this); 00232 } 00234 00236 void IncRef () 00237 { 00238 csRefTrackerAccess::TrackIncRef (this, ref_count); 00239 CS::Threading::AtomicOperations::Increment (&ref_count); 00240 } 00242 void DecRef () 00243 { 00244 csRefTrackerAccess::TrackDecRef (this, ref_count); 00245 if (CS::Threading::AtomicOperations::Decrement (&ref_count) == 0) 00246 Delete (); 00247 } 00249 int GetRefCount () const 00250 { return CS::Threading::AtomicOperations::Read (&ref_count); } 00251 }; 00252 00253 } // namespace Utility 00254 } // namespace CS 00255 00256 #endif // __CS_REFCOUNT_H__ 00257
Generated for Crystal Space 2.0 by doxygen 1.6.1