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/mutex.h" 00033 00034 #include "csutil/custom_new_disable.h" 00035 00063 template<typename Super, typename Allocator = CS::Memory::AllocatorMalloc, 00064 bool Locked = false> 00065 class scfImplementationPooled : public Super 00066 { 00067 typedef typename Super::scfClassType scfClassType; 00068 public: 00069 typedef scfImplementationPooled<Super, Allocator, Locked> 00070 scfPooledImplementationType; 00071 00072 class Pool : public CS::Threading::OptionalMutex<Locked> 00073 { 00074 friend class scfImplementationPooled<Super, Allocator, Locked>; 00075 struct Entry 00076 { 00077 Entry* next; 00078 }; 00079 CS::Memory::AllocatorPointerWrapper<Entry, Allocator> pool; 00080 size_t allocedEntries; 00081 public: 00082 Pool () : pool ((Entry*)0), allocedEntries (0) 00083 { 00084 } 00085 Pool (const Allocator& alloc) : pool (alloc, 0), allocedEntries (0) 00086 { 00087 } 00088 ~Pool () 00089 { 00090 while (pool.p != 0) 00091 { 00092 Entry* n = pool.p->next; 00093 pool.Free (pool.p); 00094 pool.p = n; 00095 } 00096 CS_ASSERT_MSG ("not all SCF-pooled instances released", 00097 allocedEntries == 0); 00098 } 00099 }; 00100 protected: 00102 Pool* scfPool; 00103 public: 00105 inline void* operator new (size_t n, Pool& p) 00106 { 00107 typedef typename Pool::Entry PoolEntry; 00108 CS_ASSERT_MSG ("Alloc size mismatches class size expected for pooled " 00109 "allocation", n == sizeof (scfClassType)); 00110 PoolEntry* newEntry; 00111 { 00112 CS::Threading::ScopedLock<Pool> lock (p); 00113 if (p.pool.p != 0) 00114 { 00115 newEntry = p.pool.p; 00116 p.pool.p = p.pool.p->next; 00117 } 00118 else 00119 { 00120 newEntry = static_cast<PoolEntry*> (p.pool.Alloc (n)); 00121 } 00122 p.allocedEntries++; 00123 } 00124 scfClassType* newInst = reinterpret_cast<scfClassType*> (newEntry); 00125 /* A bit nasty: set scfPool member of the (still unconstructed!) 00126 * instance... */ 00127 static_cast<scfPooledImplementationType*> (newInst)->scfPool = &p; 00128 return newInst; 00129 } 00130 00132 00133 inline void operator delete (void* instance, Pool& p) 00134 { 00135 typedef typename Pool::Entry PoolEntry; 00136 PoolEntry* entry = static_cast<PoolEntry*> (instance); 00137 { 00138 CS::Threading::ScopedLock<Pool> lock (p); 00139 entry->next = p.pool.p; 00140 p.pool.p = entry; 00141 p.allocedEntries--; 00142 } 00143 } 00144 inline void operator delete (void* instance) 00145 { 00146 scfClassType* object = static_cast<scfClassType*> (instance); 00147 Pool& p = *(static_cast<scfImplementationPooled*> (object)->scfPool); 00148 scfImplementationPooled::operator delete (object, p); 00149 } 00151 00153 void DecRef () 00154 { 00155 csRefTrackerAccess::TrackDecRef (this->GetSCFObject(), this->scfRefCount); 00156 this->scfRefCount--; 00157 if (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 1.4.0 by doxygen 1.5.8