csutil/refcount.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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