diff --git a/modules/core/src/precomp.hpp b/modules/core/src/precomp.hpp index 0ffde8855a..eebbda0694 100644 --- a/modules/core/src/precomp.hpp +++ b/modules/core/src/precomp.hpp @@ -388,6 +388,8 @@ cv::Mutex& getInitializationMutex(); #define CV_SINGLETON_LAZY_INIT(TYPE, INITIALIZER) CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, instance) #define CV_SINGLETON_LAZY_INIT_REF(TYPE, INITIALIZER) CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, *instance) +CV_EXPORTS void releaseTlsStorageThread(); + int cv_snprintf(char* buf, int len, const char* fmt, ...); int cv_vsnprintf(char* buf, int len, const char* fmt, va_list args); } diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index 6e882e1dde..51c7363b30 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -1583,6 +1583,9 @@ struct ThreadData size_t idx; // Thread index in TLS storage. This is not OS thread ID! }; + +static bool g_isTlsStorageInitialized = false; + // Main TLS storage class class TlsStorage { @@ -1592,6 +1595,7 @@ public: { tlsSlots.reserve(32); threads.reserve(32); + g_isTlsStorageInitialized = true; } ~TlsStorage() { @@ -1810,6 +1814,13 @@ static void WINAPI opencv_fls_destructor(void* pData) } // namespace details using namespace details; +void releaseTlsStorageThread() +{ + if (!g_isTlsStorageInitialized) + return; // nothing to release, so prefer to avoid creation of new global structures + getTlsStorage().releaseThread(); +} + TLSDataContainer::TLSDataContainer() { key_ = (int)getTlsStorage().reserveSlot(this); // Reserve key from TLS storage @@ -1893,7 +1904,7 @@ BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID lpReserved) { // Not allowed to free resources if lpReserved is non-null // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583.aspx - cv::getTlsStorage().releaseThread(); + releaseTlsStorageThread(); } } return TRUE;