message: core(tls): handle process termination / cleanup issues
diff: @@ -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
  