Make app shutdown wait for secondary threads
authorJan Vorlicek <janvorli@microsoft.com>
Wed, 25 Nov 2015 10:04:27 +0000 (11:04 +0100)
committerJan Vorlicek <janvorli@microsoft.com>
Wed, 25 Nov 2015 12:24:35 +0000 (13:24 +0100)
This change makes the CoreCLR behavior the same as the desktop CLR
w.r.t. the app shutdown and secondary threads. Now the application
waits for secondary threads to exit before exiting.

src/vm/appdomain.cpp
src/vm/appdomainnative.cpp
src/vm/assembly.cpp
src/vm/assembly.hpp
src/vm/corhost.cpp

index 1aa549c33398758b32d035e1984f39c285394763..a868babc40b8a1e6615ee2170db77cc047a1c8bd 100644 (file)
@@ -3693,7 +3693,7 @@ void SystemDomain::ExecuteMainMethod(HMODULE hMod, __in_opt LPWSTR path /*=NULL*
         pDomain->GetMulticoreJitManager().AutoStartProfile(pDomain);
 #endif
 
-        pDomain->m_pRootAssembly->ExecuteMainMethod(NULL);
+        pDomain->m_pRootAssembly->ExecuteMainMethod(NULL, FALSE /* waitForOtherThreads */);
     }
 
     pThread->ReturnToContext(&frame);
index 6dd2ffd6f7979696c22dfa51b8371ef43fc2afb6..ebc7d3339df0548468e388356cc84e6153ac84f6 100644 (file)
@@ -538,7 +538,7 @@ INT32 AppDomainNative::ExecuteAssemblyHelper(Assembly* pAssembly,
 
     EE_TRY_FOR_FINALLY(Param *, pParam, &param)
     {
-        pParam->iRetVal = pParam->pAssembly->ExecuteMainMethod(pParam->pStringArgs);
+        pParam->iRetVal = pParam->pAssembly->ExecuteMainMethod(pParam->pStringArgs, TRUE /* waitForOtherThreads */);
     }
     EE_FINALLY 
     {
index 45045e1bce307cbf6418e85c53522802c42354c4..4043353e77c0a51db08865f6c5da8493021b7756 100644 (file)
@@ -2649,7 +2649,7 @@ static void RunMainPost()
     }
 }
 
-INT32 Assembly::ExecuteMainMethod(PTRARRAYREF *stringArgs)
+INT32 Assembly::ExecuteMainMethod(PTRARRAYREF *stringArgs, BOOL waitForOtherThreads)
 {
     CONTRACTL
     {
@@ -2722,7 +2722,7 @@ INT32 Assembly::ExecuteMainMethod(PTRARRAYREF *stringArgs)
     //to decide when the process should get torn down.  So, don't call it from
     // AppDomain.ExecuteAssembly()
     if (pMeth) {
-        if (stringArgs == NULL)
+        if (waitForOtherThreads)
             RunMainPost();
     }
     else {
index 1fdc655c02bad2924b9701edd07db3e0d4e5273b..b017fb838683b109f48a2637146fabac7c9065b2 100644 (file)
@@ -500,7 +500,7 @@ public:
 
     //****************************************************************************************
     //
-    INT32 ExecuteMainMethod(PTRARRAYREF *stringArgs);
+    INT32 ExecuteMainMethod(PTRARRAYREF *stringArgs, BOOL waitForOtherThreads);
 
     //****************************************************************************************
 
index 4d6515d6d23fc0fa9fc218cebb90eb819f901082..bb6404cb38beec0ccc1344f70c4fe2a152dd6a8b 100644 (file)
@@ -1345,7 +1345,7 @@ HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId,
             arguments->SetAt(i, argument);
         }
 
-        DWORD retval = pAssembly->ExecuteMainMethod(&arguments);
+        DWORD retval = pAssembly->ExecuteMainMethod(&arguments, TRUE /* waitForOtherThreads */);
         if (pReturnValue)
         {
             *pReturnValue = retval;
@@ -2555,7 +2555,7 @@ VOID CorHost2::ExecuteMainInner(Assembly* pRootAssembly)
                // since this is the thread 0 entry point for AppX apps we use
                // the EntryPointFilter so that an unhandled exception here will
                // trigger the same behavior as in classic apps.
-        pParam->pRootAssembly->ExecuteMainMethod(NULL);
+        pParam->pRootAssembly->ExecuteMainMethod(NULL, FALSE /* waitForOtherThreads */);
     }
     PAL_EXCEPT_FILTER(EntryPointFilter)
     {