diff --git a/FWCore/Utilities/interface/ReusableObjectHolder.h b/FWCore/Utilities/interface/ReusableObjectHolder.h index 203354ca89fcf..837bb75c3f2c4 100644 --- a/FWCore/Utilities/interface/ReusableObjectHolder.h +++ b/FWCore/Utilities/interface/ReusableObjectHolder.h @@ -8,7 +8,7 @@ // /**\class edm::ReusableObjectHolder ReusableObjectHolder "ReusableObjectHolder.h" - Description: Thread safe way to do create and reuse a group of the same object type. + Description: Thread safe way to create and reuse a group of the same object type. Usage: This class can be used to safely reuse a series of objects created on demand. The reuse @@ -65,90 +65,96 @@ // Created: Fri, 31 July 2014 14:29:41 GMT // -#include -#include #include -#include "tbb/task.h" -#include "tbb/concurrent_queue.h" - +#include +#include +#include +#include namespace edm { - template + template> class ReusableObjectHolder { public: - ReusableObjectHolder():m_outstandingObjects(0){} + ReusableObjectHolder(): + m_outstandingObjects(0) + {} + + ReusableObjectHolder(ReusableObjectHolder const& iOther) = delete; + ReusableObjectHolder(ReusableObjectHolder&& iOther): - m_availableQueue(std::move(iOther.m_availableQueue)), - m_outstandingObjects(0) { - assert(0== iOther.m_outstandingObjects); + m_availableQueue(std::move(iOther.m_availableQueue)), + m_outstandingObjects(0), + m_deleter(std::move(iOther.m_deleter)) + { + assert(0 == iOther.m_outstandingObjects); } + ~ReusableObjectHolder() { assert(0==m_outstandingObjects); - T* item = 0; - while( m_availableQueue.try_pop(item)) { - delete item; + T* item = 0; + while (m_availableQueue.try_pop(item)) { + m_deleter(item); } } ///Adds the item to the cache. /// Use this function if you know ahead of time /// how many cached items you will need. - void add(std::unique_ptr iItem){ - if(0!=iItem) { - m_availableQueue.push(iItem.release()); - } - } + void add(std::unique_ptr iItem){ + if(0!=iItem) { + m_availableQueue.push(iItem.release()); + } + } ///Tries to get an already created object, - /// if none are available, returns an empty shared_ptr. + /// if none are available, returns an empty shared_ptr. /// Use this function in conjunction with add() - std::shared_ptr tryToGet() { - T* item = 0; - m_availableQueue.try_pop(item); - if (0==item) { - return std::shared_ptr{}; - } - //instead of deleting, hand back to queue + std::shared_ptr tryToGet() { + T* item = 0; + m_availableQueue.try_pop(item); + if (0==item) { + return std::shared_ptr{}; + } + //instead of deleting, hand back to queue auto pHolder = this; ++m_outstandingObjects; - return std::shared_ptr{item, [pHolder](T* iItem) {pHolder->addBack(iItem);} }; - } + return std::shared_ptr{item, [pHolder](T* iItem) {pHolder->addBack(iItem);} }; + } ///If there isn't an object already available, creates a new one using iFunc - template< typename F> - std::shared_ptr makeOrGet( F iFunc) { - std::shared_ptr returnValue; - while ( ! ( returnValue = tryToGet()) ) { - add( std::unique_ptr(iFunc()) ); - } - return returnValue; - } + template< typename F> + std::shared_ptr makeOrGet( F iFunc) { + std::shared_ptr returnValue; + while ( not ( returnValue = tryToGet()) ) { + add( std::unique_ptr(iFunc()) ); + } + return returnValue; + } ///If there is an object already available, passes the object to iClearFunc and then /// returns the object. ///If there is not an object already available, creates a new one using iMakeFunc - template< typename FM, typename FC> - std::shared_ptr makeOrGetAndClear( FM iMakeFunc, FC iClearFunc) { - std::shared_ptr returnValue; - while ( ! ( returnValue = tryToGet()) ) { - add( std::unique_ptr(iMakeFunc()) ); - } - iClearFunc(returnValue.get()); - return returnValue; - } + template< typename FM, typename FC> + std::shared_ptr makeOrGetAndClear( FM iMakeFunc, FC iClearFunc) { + std::shared_ptr returnValue; + while ( not ( returnValue = tryToGet()) ) { + add( std::unique_ptr(iMakeFunc() ) ); + } + iClearFunc(returnValue.get()); + return returnValue; + } private: void addBack(T* iItem){ - m_availableQueue.push(iItem); + m_availableQueue.push(iItem); --m_outstandingObjects; - } - - tbb::concurrent_queue m_availableQueue; + } + + tbb::concurrent_queue m_availableQueue; std::atomic m_outstandingObjects; + Deleter m_deleter; }; } - - #endif /* end of include guard: FWCore_Utilities_ReusableObjectHolder_h */