core(TLS): add cleanup() method
authorAlexander Alekhin <alexander.alekhin@intel.com>
Wed, 15 Feb 2017 17:20:38 +0000 (20:20 +0300)
committerAlexander Alekhin <alexander.alekhin@intel.com>
Tue, 21 Feb 2017 13:08:23 +0000 (16:08 +0300)
modules/core/include/opencv2/core/utility.hpp
modules/core/src/system.cpp

index 0b90383..93d599c 100644 (file)
@@ -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<T*> &data) const
     {
         std::vector<void*> &dataVoid = reinterpret_cast<std::vector<void*>&>(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
index 890ca96..37a1241 100644 (file)
@@ -1086,7 +1086,7 @@ public:
     }
 
     // Release TLS storage index and pass associated data to caller
-    void releaseSlot(size_t slotIdx, std::vector<void*> &dataVec)
+    void releaseSlot(size_t slotIdx, std::vector<void*> &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<void*> 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<void*> 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