csutil/pooledscfclass.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/pooledscfclass.h
Go to the documentation of this file.

    00001 /*
    00002     Copyright (C) 2004 by Jorrit Tyberghein
    00003               (C) 2004 by Frank Richter
    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_UTIL_POOLEDSCFCLASS_H__
    00021 #define __CS_UTIL_POOLEDSCFCLASS_H__
    00022
    00031 #include "csutil/scf.h"
    00032 #include "csutil/threading/atomicops.h"
    00033 #include "csutil/threading/mutex.h"
    00034
    00035 #include "csutil/custom_new_disable.h"
    00036
    00064 template<typename Super, typename Allocator = CS::Memory::AllocatorMalloc,
    00065   bool Locked = false>
    00066 class scfImplementationPooled : public Super
    00067 {
    00068   typedef typename Super::scfClassType scfClassType;
    00069 public:
    00070   typedef scfImplementationPooled<Super, Allocator, Locked>
    00071     scfPooledImplementationType;
    00072
    00073   class Pool : public CS::Threading::OptionalMutex<Locked>
    00074   {
    00075     friend class scfImplementationPooled<Super, Allocator, Locked>;
    00076     struct Entry
    00077     {
    00078       Entry* next;
    00079     };
    00080     CS::Memory::AllocatorPointerWrapper<Entry, Allocator> pool;
    00081     size_t allocedEntries;
    00082   public:
    00083     Pool () : pool ((Entry*)0), allocedEntries (0)
    00084     {
    00085     }
    00086     Pool (const Allocator& alloc) : pool (alloc, 0), allocedEntries (0)
    00087     {
    00088     }
    00089     ~Pool ()
    00090     {
    00091       while (pool.p != 0)
    00092       {
    00093         Entry* n = pool.p->next;
    00094         pool.Free (pool.p);
    00095         pool.p = n;
    00096       }
    00097       CS_ASSERT_MSG ("not all SCF-pooled instances released",
    00098         allocedEntries == 0);
    00099     }
    00100   };
    00101 protected:
    00103   Pool* scfPool;
    00104 public:
    00106   inline void* operator new (size_t n, Pool& p)
    00107   {
    00108     typedef typename Pool::Entry PoolEntry;
    00109     CS_ASSERT_MSG ("Alloc size mismatches class size expected for pooled "
    00110       "allocation", n == sizeof (scfClassType));
    00111     PoolEntry* newEntry;
    00112     {
    00113       CS::Threading::ScopedLock<Pool> lock (p);
    00114       if (p.pool.p != 0)
    00115       {
    00116         newEntry = p.pool.p;
    00117         p.pool.p = p.pool.p->next;
    00118       }
    00119       else
    00120       {
    00121         newEntry = static_cast<PoolEntry*> (p.pool.Alloc (n));
    00122       }
    00123       p.allocedEntries++;
    00124     }
    00125     scfClassType* newInst = reinterpret_cast<scfClassType*> (newEntry);
    00126     /* A bit nasty: set scfPool member of the (still unconstructed!)
    00127      * instance... */
    00128     static_cast<scfPooledImplementationType*> (newInst)->scfPool = &p;
    00129     return newInst;
    00130   }
    00131
    00133
    00134   inline void operator delete (void* instance, Pool& p)
    00135   {
    00136     typedef typename Pool::Entry PoolEntry;
    00137     PoolEntry* entry = static_cast<PoolEntry*> (instance);
    00138     {
    00139       CS::Threading::ScopedLock<Pool> lock (p);
    00140       entry->next = p.pool.p;
    00141       p.pool.p = entry;
    00142       p.allocedEntries--;
    00143     }
    00144   }
    00145   inline void operator delete (void* instance)
    00146   {
    00147     scfClassType* object = static_cast<scfClassType*> (instance);
    00148     Pool& p = *(static_cast<scfImplementationPooled*> (object)->scfPool);
    00149     scfImplementationPooled::operator delete (object, p);
    00150   }
    00152
    00154   void DecRef ()
    00155   {
    00156     csRefTrackerAccess::TrackDecRef (this->GetSCFObject(), this->scfRefCount);
    00157     if (CS::Threading::AtomicOperations::Decrement (&this->scfRefCount) == 0)
    00158     {
    00159       delete this->GetSCFObject();
    00160     }
    00161   }
    00162
    00164
    00167   scfImplementationPooled (scfClassType* object) :
    00168     Super (object) {}
    00169   template<typename A>
    00170   scfImplementationPooled (scfClassType* object, A a) :
    00171     Super (object, a) {}
    00172   template<typename A, typename B>
    00173   scfImplementationPooled (scfClassType* object, A a, B b) :
    00174     Super (object, a, b) {}
    00175   template<typename A, typename B, typename C>
    00176   scfImplementationPooled (scfClassType* object, A a, B b, C c) :
    00177     Super (object, a, b, c) {}
    00178   template<typename A, typename B, typename C, typename D>
    00179   scfImplementationPooled (scfClassType* object, A a, B b, C c, D d) :
    00180     Super (object, a, b, c, d) {}
    00181   template<typename A, typename B, typename C, typename D, typename E>
    00182   scfImplementationPooled (scfClassType* object, A a, B b, C c, D d, E e) :
    00183     Super (object, a, b, c, d, e) {}
    00185 };
    00186
    00189 #include "csutil/custom_new_enable.h"
    00190
    00191 #endif // __CS_UTIL_POOLEDSCFCLASS_H__