|
|
|
@ -1800,12 +1800,31 @@ static TlsStorage &getTlsStorage() |
|
|
|
|
#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
|
|
|
|
|