//******************************************************************* // // License: See top level LICENSE.txt file. // // Author: Garrett Potts // //********************************************************************** // $Id: ossimPool.h 9968 2006-11-29 14:01:53Z gpotts $ #ifndef ossimPool_HEADER #define ossimPool_HEADER #include #include #include #include #include #include #include #include #define OSSIM_DEFAULT_POOL_SIZE (ossim_uint32)10 /** * Container pool to be used for things like threads. */ template class ossimPool { public: /** * Contructor * @param n Number of pooled objects to create. */ ossimPool(ossim_uint32 n=OSSIM_DEFAULT_POOL_SIZE) throw(std::bad_alloc) : thePool(n) { for(ossim_uint32 idx = 0; idx < n; ++idx) { try { ossimPoolObject* poolObject = new ossimPoolObject(); poolObject->theAvailableFlag = true; poolObject->theObjectPtr = new T(); thePool[idx] = poolObject; } catch(std::bad_alloc) { ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimPool::ossimPool(): Bad allocation" << endl; } } } /** * Destructor */ ~ossimPool() { thePool.clear(); } /** * @return A pooled object of type T*. Will return null if the pool is * used up or pool size is zero. */ T* checkout() { T* t = NULL; theCriticalSectionMutex.lock(); for (ossim_uint32 idx = 0; idx < thePool.size(); ++idx) { if (thePool[idx]->theAvailableFlag == true) { thePool[idx]->theAvailableFlag = false; t = thePool[idx]->theObjectPtr; break; } } theCriticalSectionMutex.unlock(); return t; } /** * Resets and eturns object to the pool. * @param obj Object to be returned to the pool. * * @note The object is required to have a "reset()" method. * * @return Returns void unless object was not from pool then throws * a std::out_of_range error. */ void checkin(T* obj) throw(std::out_of_range) { theCriticalSectionMutex.lock(); for (ossim_uint32 idx = 0; idx < thePool.size(); ++idx) { if (obj == thePool[idx]->theObjectPtr) { obj->reset(); thePool[idx]->theAvailableFlag = true; theCriticalSectionMutex.unlock(); return; } } theCriticalSectionMutex.unlock(); throw std::out_of_range(string("ossimPool::checkin Error Object not managed by this pool!")); } /** * Outputs object addresses and theAvailableFlag. */ std::ostream& print(std::ostream& out) const { for (ossim_uint32 idx = 0; idx < thePool.size(); ++idx) { out << "obj address: " << (hex) << thePool[idx]->theObjectPtr << " is " << (thePool[idx]->theAvailableFlag ? "available":"unavailable") << endl; } return out; } template friend std::ostream& operator<<(std::ostream& out, const ossimPool& obj) { return obj.print(out); } protected: std::vector*> thePool; }; #endif /* #ifndef ossimPool_HEADER */