Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2016-04-06 03:11:17 +0300
committerJan Vorlicek <janvorli@microsoft.com>2016-04-06 03:11:17 +0300
commitc7dea7f7679e7b032cf28d99a7ee67424cbe2047 (patch)
tree1cd8bb1e62873f5d25310631db5e1c7c13514d26 /src/Native/Runtime/startup.cpp
parentf9dd49a67e14539c14df353141faf3a215a3aebd (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.cpp24
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