#endif // CV_USE_FLS
#endif // _WIN32
+ static TlsAbstraction* const g_force_initialization_of_TlsAbstraction
+ #if defined __GNUC__
+ __attribute__((unused))
+ #endif
+ = getTlsAbstraction();
+
++
+#else // OPENCV_DISABLE_THREAD_SUPPORT
+
+// no threading (OPENCV_DISABLE_THREAD_SUPPORT=ON)
+class TlsStorage
+{
+public:
+ TlsStorage()
+ {
+ slots.reserve(32);
+ }
+ ~TlsStorage()
+ {
+ for (size_t slotIdx = 0; slotIdx < slots.size(); slotIdx++)
+ {
+ SlotInfo& s = slots[slotIdx];
+ TLSDataContainer* container = s.container;
+ if (container && s.data)
+ {
+ container->deleteDataInstance(s.data); // Can't use from SlotInfo destructor
+ s.data = nullptr;
+ }
+ }
+ }
+
+ // Reserve TLS storage index
+ size_t reserveSlot(TLSDataContainer* container)
+ {
+ size_t slotsSize = slots.size();
+ for (size_t slot = 0; slot < slotsSize; slot++)
+ {
+ SlotInfo& s = slots[slot];
+ if (s.container == NULL)
+ {
+ CV_Assert(!s.data);
+ s.container = container;
+ return slot;
+ }
+ }
+
+ // create new slot
+ slots.push_back(SlotInfo(container));
+ return slotsSize;
+ }
+
+ // Release TLS storage index and pass associated data to caller
+ void releaseSlot(size_t slotIdx, std::vector<void*> &dataVec, bool keepSlot = false)
+ {
+ CV_Assert(slotIdx < slots.size());
+ SlotInfo& s = slots[slotIdx];
+ void* data = s.data;
+ if (data)
+ {
+ dataVec.push_back(data);
+ s.data = nullptr;
+ }
+ if (!keepSlot)
+ {
+ s.container = NULL; // mark slot as free (see reserveSlot() implementation)
+ }
+ }
+
+ // Get data by TLS storage index
+ void* getData(size_t slotIdx) const
+ {
+ CV_Assert(slotIdx < slots.size());
+ const SlotInfo& s = slots[slotIdx];
+ return s.data;
+ }
+
+ // Gather data from threads by TLS storage index
+ void gather(size_t slotIdx, std::vector<void*> &dataVec)
+ {
+ CV_Assert(slotIdx < slots.size());
+ SlotInfo& s = slots[slotIdx];
+ void* data = s.data;
+ if (data)
+ dataVec.push_back(data);
+ return;
+ }
+
+ // Set data to storage index
+ void setData(size_t slotIdx, void* pData)
+ {
+ CV_Assert(slotIdx < slots.size());
+ SlotInfo& s = slots[slotIdx];
+ s.data = pData;
+ }
+
+private:
+ struct SlotInfo
+ {
+ SlotInfo(TLSDataContainer* _container) : container(_container), data(nullptr) {}
+ TLSDataContainer* container; // attached container (to dispose data)
+ void* data;
+ };
+ std::vector<struct SlotInfo> slots;
+};
+
+static TlsStorage& getTlsStorage()
+{
+ static TlsStorage g_storage; // no threading
+ return g_storage;
+}
+
+#endif // OPENCV_DISABLE_THREAD_SUPPORT
+
} // namespace details
using namespace details;