Hi all<div>Here is my objectpool implemention which inspired by boost pool.</div><div>Which have following features.</div><div><div>Features:</div><div>1.Allocate an object from pre-allocate memory, when free an object just put it back to pool.</div> <div>2.Call object's contructor at pool memory allocating or get object from pool, or do nothing.</div><div>3.Call object's deconstructor when "delete" object if constructor's been calling at "new" object</div> <div>3.Call object's deconstructor when destroy objectpool if constructor's been calling at memory allocating</div><div>4.Can pass an function object to be invoke when "new" object, this can be used as a constructor if object's constructor don't be invokded when "new" object</div> <div><div>5.Thread safe can be enable/disable by tempalte parameter</div><div>6.Callback can be raw pointer is T is not inherit from enable_shared_from this</div><div>can be shared_ptr vers vice.</div></div> <div><br></div><div>There are several tasks need to do, like the allnodesset can be generated at callring of foreach. Delegate memory allocating to allocator, etc..</div><div><br></div><div><br></div><div> The whole project and unit test can be found at</div> <div><a href="https://maxsrecyclebin.svn.sourceforge.net/svnroot/maxsrecyclebin/objectpool/">https://maxsrecyclebin.svn.sourceforge.net/svnroot/maxsrecyclebin/objectpool/</a></div><div><div><br></div><div>Is there any comments?</div> <div>Thanks</div><div>//////////////////////////////////////////////////////////////////////////////////////</div><div>#include <istream></div><div>#include <list></div><div>#include <boost/shared_ptr.hpp></div> <div>#include <boost/bind.hpp></div><div>#include <set></div><div>#include <algorithm></div><div>#include <boost/type_traits.hpp></div><div>#include <boost/enable_shared_from_this.hpp></div><div> #include <boost/thread/pthread/mutex.hpp></div><div>namespace maxutility {</div><div>enum InitialType {None,ObjInitial,PoolAllocate};</div><div>template <typename T></div><div>class DummyCallableObj</div><div> {</div><div>public:</div><div> void operator ()(boost::shared_ptr<T> &ptr)</div><div> {</div><div> //do nothing</div><div> }</div><div>};</div><div>template<bool isthreadsafe></div><div>class obthreadlock;</div> <div>template<></div><div>class obthreadlock<true></div><div>{</div><div>public:</div><div> void lock(){obmutex.lock();}</div><div> bool try_lock(){return obmutex.try_lock();}</div><div> void unlock(){obmutex.unlock();}</div> <div>private:</div><div> boost::mutex obmutex;</div><div>};</div><div>template<></div><div>class obthreadlock<false></div><div>{</div><div>public:</div><div> void lock(){};</div><div> bool try_lock(){return true;};</div> <div> void unlock(){};</div><div>};</div><div>template <typename T,bool isthreadsafe=false,typename InitalFunction=DummyCallableObj<T> ></div><div>class ObjectPool</div><div>{</div><div>#define LOCAL_LOCK boost::lock_guard<obthreadlock<isthreadsafe> > lg(obthreadlock_);</div> <div>protected:</div><div> /**</div><div> * @brief Declaration for furture usage</div><div> **/</div><div> typedef T Node;</div><div> typedef std::list<char *> FRAGMENTTYPE;</div><div> typedef std::list<Node *> NODELIST;</div> <div> </div><div>public:</div><div> ObjectPool(InitialType initialtype=ObjInitial,size_t initialsize=512,size_t maxsize=0)</div><div> {</div><div><br></div><div> busyCount=0;</div><div> this->poolsize=0;</div> <div> this->initialtype=initialtype;</div><div> this->maxsize=maxsize;</div><div> extend(initialsize);</div><div> }</div><div> ObjectPool(InitalFunction initalFunction=DummyCallableObj<T>(),</div> <div> InitialType initialtype=PoolAllocate,</div><div> size_t initialsize=512,</div><div> size_t maxsize=0) //:ObjectPool(initialtype,initialsize,maxsize) //Delegating constructors, c++11 only</div> <div> {</div><div> busyCount=0;</div><div> this->poolsize=0;</div><div> this->initialtype=initialtype;</div><div> this->maxsize=maxsize;</div><div> this->initalFunction=initalFunction;</div> <div> extend(initialsize);</div><div> }</div><div> ~ObjectPool()</div><div> {</div><div> if(0!=busyCount)</div><div> throw new std::exception();</div><div> if(PoolAllocate==initialtype)</div> <div> for(Node *p:allnodes)</div><div> p->~Node();</div><div> for(char *pFragment:fragments)</div><div> delete pFragment;</div><div> }</div><div> virtual boost::shared_ptr<T> create()</div> <div> {</div><div> LOCAL_LOCK;</div><div> boost::shared_ptr<T> ptr(static_cast<T*>(getFreeNode()),boost::bind(&ObjectPool<T,isthreadsafe,InitalFunction>::free,this,_1));</div><div> initalFunction(ptr);</div> <div> return ptr;</div><div> }</div><div><br></div><div><br></div><div> bool empty()</div><div> {</div><div> return !busyCount;</div><div> }</div><div> size_t size()</div><div> {</div><div> return busyCount;</div><div> }</div><div> size_t capacity()</div><div> {</div><div> return poolsize;</div><div> }</div><div> template <typename FUNCTION></div><div> void foreach(FUNCTION f)</div> <div> {</div><div> LOCAL_LOCK;</div><div> NODELIST freenodes=this->freenodes; //make a local copy</div><div> freenodes.sort();</div><div> NODELIST busynodes(allnodes.size());</div><div> typename NODELIST::iterator busynodesend=std::set_difference(</div> <div> allnodes.begin(),allnodes.end(),freenodes.begin(),freenodes.end(),busynodes.begin()</div><div> );</div><div><br></div><div> for(typename NODELIST::iterator iter=busynodes.begin();</div><div> iter!=busynodesend;</div><div> iter++)</div><div> {</div><div> invokeFunction<FUNCTION,Node,</div><div> boost::is_base_of<boost::enable_shared_from_this<Node>,Node >::value >()(f,*iter);</div> <div> }</div><div> }</div><div>protected:</div><div> template<typename _Function,typename N,bool isuseshareptr></div><div> class invokeFunction;</div><div> template<typename _Function,typename N></div> <div> class invokeFunction<_Function,N,false></div><div> {</div><div> public:</div><div> void operator ()(_Function __f,N *p)</div><div> {</div><div> __f(p);</div><div> }</div> <div> };</div><div> template<typename _Function,typename N></div><div> class invokeFunction<_Function,N,true></div><div> {</div><div> public:</div><div> void operator ()(_Function __f,N *p)</div> <div> {</div><div> boost::shared_ptr<N> ptr=p->shared_from_this();</div><div> __f(ptr);</div><div> }</div><div> };</div><div> </div><div> </div><div>protected:</div><div> void free(T *p)</div><div> {</div><div> LOCAL_LOCK;</div><div> if(!p)</div><div> return;</div><div> destroyObj(static_cast<Node*>(p),ObjInitial);</div><div> //removeBusyNode(static_cast<Node*>(p));</div> <div> freenodes.push_back(static_cast<Node*>(p));</div><div> busyCount--;</div><div> }</div><div> Node *getFreeNode()</div><div> {</div><div> Node *ptr=nullptr;</div><div> if(freenodes.empty()) //no new free node</div> <div> if(!extend()) //try to extend</div><div> return ptr; //false</div><div> ptr=freenodes.front(); //now it must contain free node</div><div> freenodes.pop_front();</div><div> </div><div><br></div><div> constructObj(ptr,ObjInitial);</div><div> busyCount++;</div><div> return ptr;</div><div> }</div><div> bool extend(size_t size=0)</div><div> {</div><div> if((0!=maxsize&&poolsize>=maxsize&&poolsize!=0)</div> <div><br></div><div> )</div><div> return false; //we reach the maximum size</div><div> //poolsize=0 first allocation</div><div> //size=0 extend twice size of current size</div><div> //poolsize=size=0 we got a problem</div> <div> size_t extSize=((0==poolsize)?size:2*poolsize);</div><div> char *pFragment=new char[extSize*sizeof(Node)];</div><div> if(!pFragment)</div><div> return false;</div><div> fragments.push_back(pFragment);</div> <div> poolsize+=extSize;</div><div> for(Node *p=(Node*)pFragment; extSize--; p++)</div><div> {</div><div> constructObj(p,PoolAllocate);</div><div> freenodes.push_back(p);</div><div> allnodes.push_back(p);</div><div> }</div><div> allnodes.sort();</div><div> return true;</div><div> }</div><div> void constructObj(Node *p,InitialType phase)</div><div> {</div><div> if(phase==initialtype)</div><div> ::new(p)Node;</div><div> }</div><div> void destroyObj(Node *p,InitialType phase)</div><div> {</div><div> if(phase==initialtype)</div><div> p->~Node();</div> <div> }</div><div><br></div><div> size_t poolsize;</div><div> InitialType initialtype;</div><div> size_t maxsize;</div><div> FRAGMENTTYPE fragments;</div><div> NODELIST freenodes;</div><div> NODELIST allnodes;</div> <div> size_t busyCount;</div><div> InitalFunction initalFunction;</div><div> obthreadlock<isthreadsafe> obthreadlock_;</div><div>};</div><div>};</div></div><div><br></div></div>