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__
Generated for Crystal Space 2.0 by doxygen 1.6.1