CrystalSpace

Public API Reference

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.7.6.1