diff options
author | Jan Vorlicek <janvorli@microsoft.com> | 2016-04-06 03:11:17 +0300 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2016-04-06 03:11:17 +0300 |
commit | c7dea7f7679e7b032cf28d99a7ee67424cbe2047 (patch) | |
tree | 1cd8bb1e62873f5d25310631db5e1c7c13514d26 /src/Native/Runtime/startup.cpp | |
parent | f9dd49a67e14539c14df353141faf3a215a3aebd (diff) |
This change adds back a logic to prevent deadlock at process shutdown that was incorrectly reverted when a change from github CoreRT was merged in.
[tfs-changeset: 1593273]
Diffstat (limited to 'src/Native/Runtime/startup.cpp')
-rw-r--r-- | src/Native/Runtime/startup.cpp | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/src/Native/Runtime/startup.cpp b/src/Native/Runtime/startup.cpp index 145b4dddd..2d949e0e2 100644 --- a/src/Native/Runtime/startup.cpp +++ b/src/Native/Runtime/startup.cpp @@ -223,6 +223,8 @@ void DllThreadAttach(HANDLE /*hPalInstance*/) // threads themselves will do this on their first reverse pinvoke. } +volatile bool g_processShutdownHasStarted = false; + void DllThreadDetach() { // BEWARE: loader lock is held here! @@ -231,18 +233,30 @@ void DllThreadDetach() Thread* pCurrentThread = ThreadStore::GetCurrentThreadIfAvailable(); if (pCurrentThread != NULL && !pCurrentThread->IsDetached()) { - ASSERT_UNCONDITIONALLY("Detaching thread whose home fiber has not been detached"); - RhFailFast(); + // Once shutdown starts, RuntimeThreadShutdown callbacks are ignored, implying that + // it is no longer guaranteed that exiting threads will be detached. + if (!g_processShutdownHasStarted) + { + ASSERT_UNCONDITIONALLY("Detaching thread whose home fiber has not been detached"); + RhFailFast(); + } } } void __stdcall RuntimeThreadShutdown(void* thread) { - // Note: loader lock is *not* held here! + // Note: loader lock is normally *not* held here! + // The one exception is that the loader lock may be held during the thread shutdown callback + // that is made for the single thread that runs the final stages of orderly process + // shutdown (i.e., the thread that delivers the DLL_PROCESS_DETACH notifications when the + // process is being torn down via an ExitProcess call). UNREFERENCED_PARAMETER(thread); ASSERT((Thread*)thread == ThreadStore::GetCurrentThread()); - ThreadStore::DetachCurrentThread(); + if (!g_processShutdownHasStarted) + { + ThreadStore::DetachCurrentThread(); + } } COOP_PINVOKE_HELPER(UInt32_BOOL, RhpRegisterModule, (ModuleHeader *pModuleHeader)) @@ -318,6 +332,8 @@ COOP_PINVOKE_HELPER(void, RhpShutdownHelper, (UInt32 /*uExitCode*/)) #ifdef FEATURE_PROFILING GetRuntimeInstance()->WriteProfileInfo(); #endif // FEATURE_PROFILING + // Indicate that runtime shutdown is complete and that the caller is about to start shutting down the entire process. + g_processShutdownHasStarted = true; } #endif // !DACCESS_COMPILE |