#ifndef _WIN32 // pthread key destructor
static void opencv_tls_destructor(void* pData)
{
+ if (!g_isTlsStorageInitialized)
+ return; // nothing to release, so prefer to avoid creation of new global structures
getTlsStorage().releaseThread(pData);
}
#else // _WIN32
#ifdef CV_USE_FLS
static void WINAPI opencv_fls_destructor(void* pData)
{
+ // Empiric detection of ExitProcess call
+ DWORD code = STILL_ACTIVE/*259*/;
+ BOOL res = GetExitCodeProcess(GetCurrentProcess(), &code);
+ if (res && code != STILL_ACTIVE)
+ {
+ // Looks like we are in ExitProcess() call
+ // This is FLS specific only because their callback is called before DllMain.
+ // TLS doesn't have similar problem, DllMain() is called first which mark __termination properly.
+ // Note: this workaround conflicts with ExitProcess() steps order described in documentation, however it works:
+ // 3. ... called with DLL_PROCESS_DETACH
+ // 7. The termination status of the process changes from STILL_ACTIVE to the exit value of the process.
+ // (ref: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-exitprocess)
+ cv::__termination = true;
+ }
+
+ if (!g_isTlsStorageInitialized)
+ return; // nothing to release, so prefer to avoid creation of new global structures
getTlsStorage().releaseThread(pData);
}
#endif // CV_USE_FLS