diff --git a/modules/core/include/opencv2/core/utility.hpp b/modules/core/include/opencv2/core/utility.hpp index 0b9038303e..93d599ccee 100644 --- a/modules/core/include/opencv2/core/utility.hpp +++ b/modules/core/include/opencv2/core/utility.hpp @@ -627,6 +627,9 @@ public: virtual void deleteDataInstance(void* pData) const = 0; int key_; + +public: + void cleanup(); //! Release created TLS data container objects. It is similar to release() call, but it keeps TLS container valid. }; // Main TLS data class @@ -638,13 +641,15 @@ public: inline ~TLSData() { release(); } // Release key and delete associated data inline T* get() const { return (T*)getData(); } // Get data associated with key - // Get data from all threads + // Get data from all threads inline void gather(std::vector &data) const { std::vector &dataVoid = reinterpret_cast&>(data); gatherData(dataVoid); } + inline void cleanup() { TLSDataContainer::cleanup(); } + private: virtual void* createDataInstance() const {return new T;} // Wrapper to allocate data by template virtual void deleteDataInstance(void* pData) const {delete (T*)pData;} // Wrapper to release data by template diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index 890ca96f10..37a12411b3 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -1086,7 +1086,7 @@ public: } // Release TLS storage index and pass associated data to caller - void releaseSlot(size_t slotIdx, std::vector &dataVec) + void releaseSlot(size_t slotIdx, std::vector &dataVec, bool keepSlot = false) { AutoLock guard(mtxGlobalAccess); CV_Assert(tlsSlots.size() > slotIdx); @@ -1099,12 +1099,13 @@ public: if (thread_slots.size() > slotIdx && thread_slots[slotIdx]) { dataVec.push_back(thread_slots[slotIdx]); - threads[i]->slots[slotIdx] = 0; + thread_slots[slotIdx] = NULL; } } } - tlsSlots[slotIdx] = 0; + if (!keepSlot) + tlsSlots[slotIdx] = 0; } // Get data by TLS storage index @@ -1196,9 +1197,18 @@ void TLSDataContainer::release() std::vector data; data.reserve(32); getTlsStorage().releaseSlot(key_, data); // Release key and get stored data for proper destruction + key_ = -1; + for(size_t i = 0; i < data.size(); i++) // Delete all associated data + deleteDataInstance(data[i]); +} + +void TLSDataContainer::cleanup() +{ + std::vector data; + data.reserve(32); + getTlsStorage().releaseSlot(key_, data, true); // Extract stored data with removal from TLS tables for(size_t i = 0; i < data.size(); i++) // Delete all associated data deleteDataInstance(data[i]); - key_ = -1; } void* TLSDataContainer::getData() const