Recognize STA\MTA Attribute For Main Function (#15652)
authorAnirudh Agnihotry <anirudhagnihotry098@gmail.com>
Fri, 29 Dec 2017 00:35:12 +0000 (16:35 -0800)
committerJan Kotas <jkotas@microsoft.com>
Fri, 29 Dec 2017 00:35:12 +0000 (16:35 -0800)
* Apartment state set for main method

* g_fWeownprocess removed and CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_FinalizeOnShutdown) set

src/inc/clrconfigvalues.h
src/vm/appdomain.cpp
src/vm/appdomain.hpp
src/vm/assembly.cpp
src/vm/ceemain.cpp
src/vm/comsynchronizable.cpp
src/vm/corhost.cpp
src/vm/eeconfig.cpp
src/vm/eeconfig.h

index b6e5342..6ddb566 100644 (file)
@@ -937,7 +937,6 @@ RETAIL_CONFIG_STRING_INFO(INTERNAL_EventNameFilter, W("EventNameFilter"), "")
 CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_ExposeExceptionsInCOM, W("ExposeExceptionsInCOM"), "")
 RETAIL_CONFIG_DWORD_INFO(EXTERNAL_ComInsteadOfManagedRemoting, W("PreferComInsteadOfManagedRemoting"), 0, "When communicating with a cross app domain CCW, use COM instead of managed remoting.")
 CONFIG_DWORD_INFO(INTERNAL_GenerateStubForHost, W("GenerateStubForHost"), 0, "Forces the host hook stub to be built for all unmanaged calls, even when not running hosted.")
-RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(EXTERNAL_legacyApartmentInitPolicy, W("legacyApartmentInitPolicy"), "")
 RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(EXTERNAL_legacyComHierarchyVisibility, W("legacyComHierarchyVisibility"), "")
 RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(EXTERNAL_legacyComVTableLayout, W("legacyComVTableLayout"), "")
 RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(EXTERNAL_newComVTableLayout, W("newComVTableLayout"), "")
index 07e3280..bab3f65 100644 (file)
@@ -3081,39 +3081,10 @@ Thread::ApartmentState SystemDomain::GetEntryPointThreadAptState(IMDInternalImpo
     return Thread::AS_Unknown;
 }
 
-void SystemDomain::SetThreadAptState (IMDInternalImport* pScope, Thread::ApartmentState state)
+void SystemDomain::SetThreadAptState (Thread::ApartmentState state)
 {
     STANDARD_VM_CONTRACT;
 
-    BOOL fIsLegacy = FALSE;
-
-    // Check for legacy behavior regarding COM Apartment state of the main thread.
-
-#define METAMODEL_MAJOR_VER_WITH_NEW_BEHAVIOR 2
-#define METAMODEL_MINOR_VER_WITH_NEW_BEHAVIOR 0
-
-    LPCSTR pVer;
-    IfFailThrow(pScope->GetVersionString(&pVer));
-    
-    // Does this look like a version?
-    if (pVer != NULL)
-    {
-        // Is it 'vN.' where N is a digit?
-        if ((pVer[0] == 'v' || pVer[0] == 'V') &&
-            IS_DIGIT(pVer[1]) &&
-            (pVer[2] == '.') )
-        {
-            // Looks like a version.  Is it lesser than v2.0 major version where we start using new behavior?
-            fIsLegacy = DIGIT_TO_INT(pVer[1]) < METAMODEL_MAJOR_VER_WITH_NEW_BEHAVIOR;
-        }
-    }
-
-    if (!fIsLegacy && g_pConfig != NULL)
-    {
-        fIsLegacy = g_pConfig->LegacyApartmentInitPolicy();
-    }
-
-
     Thread* pThread = GetThread();
     _ASSERTE(pThread);
 
@@ -3122,14 +3093,8 @@ void SystemDomain::SetThreadAptState (IMDInternalImport* pScope, Thread::Apartme
         Thread::ApartmentState pState = pThread->SetApartment(Thread::AS_InSTA, TRUE);
         _ASSERTE(pState == Thread::AS_InSTA);
     }
-    else if ((state == Thread::AS_InMTA) || (!fIsLegacy))
+    else if (state == Thread::AS_InMTA)
     {
-        // If either MTAThreadAttribute is specified or (if no attribute is specified and we are not
-        // running in legacy mode), then
-        // we will set the apartment state to MTA. The reason for this is to ensure the apartment
-        // state is consistent and reliably set. Without this, the apartment state for the main
-        // thread would be undefined and would actually be dependent on if the assembly was
-        // ngen'd, which other type were loaded, etc.
         Thread::ApartmentState pState = pThread->SetApartment(Thread::AS_InMTA, TRUE);
         _ASSERTE(pState == Thread::AS_InMTA);
     }
index 8689ff8..ea1c471 100644 (file)
@@ -4267,7 +4267,7 @@ public:
 
 #if defined(FEATURE_COMINTEROP_APARTMENT_SUPPORT) && !defined(CROSSGEN_COMPILE)
     static Thread::ApartmentState GetEntryPointThreadAptState(IMDInternalImport* pScope, mdMethodDef mdMethod);
-    static void SetThreadAptState(IMDInternalImport* pScope, Thread::ApartmentState state);
+    static void SetThreadAptState(Thread::ApartmentState state);
 #endif
     static BOOL SetGlobalSharePolicyUsingAttribute(IMDInternalImport* pScope, mdMethodDef mdMethod);
 
index 32a7cd9..e93d2c3 100644 (file)
@@ -1790,7 +1790,22 @@ INT32 Assembly::ExecuteMainMethod(PTRARRAYREF *stringArgs, BOOL waitForOtherThre
         GCX_COOP();
 
         pMeth = GetEntryPoint();
+
         if (pMeth) {
+            {
+#ifdef FEATURE_COMINTEROP
+                GCX_PREEMP();
+
+                Thread::ApartmentState state = Thread::AS_Unknown;
+                state = SystemDomain::GetEntryPointThreadAptState(pMeth->GetMDImport(), pMeth->GetMemberDef());
+
+                // If the entry point has an explicit thread apartment state, set it
+                // before running the AppDomainManager initialization code.
+                if (state == Thread::AS_InSTA || state == Thread::AS_InMTA)
+                    SystemDomain::SetThreadAptState(state);
+#endif // FEATURE_COMINTEROP
+            }
+
             RunMainPre();
 
             
index 8b44945..3f6492b 100644 (file)
@@ -2037,8 +2037,6 @@ BOOL IsThreadInSTA()
 }
 #endif
 
-BOOL g_fWeOwnProcess = FALSE;
-
 static LONG s_ActiveShutdownThreadCount = 0;
 
 // ---------------------------------------------------------------------------
@@ -2074,15 +2072,8 @@ DWORD WINAPI EEShutDownProcForSTAThread(LPVOID lpParameter)
     {
         action = eRudeExitProcess;
     }
-    UINT exitCode;
-    if (g_fWeOwnProcess)
-    {
-        exitCode = GetLatchedExitCode();
-    }
-    else
-    {
-        exitCode = HOST_E_EXITPROCESS_TIMEOUT;
-    }
+
+    UINT exitCode = GetLatchedExitCode();
     EEPolicy::HandleExitProcessFromEscalation(action, exitCode);
 
     return 0;
@@ -2176,7 +2167,7 @@ void STDMETHODCALLTYPE EEShutDown(BOOL fIsDllUnloading)
     }
 
 #ifdef FEATURE_COMINTEROP
-    if (!fIsDllUnloading && IsThreadInSTA())
+    if (!fIsDllUnloading && CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_FinalizeOnShutdown) && IsThreadInSTA())
     {
         // #STAShutDown
         // 
index 472ca34..1956121 100644 (file)
@@ -1109,13 +1109,10 @@ FCIMPL1(void, ThreadNative::StartupSetApartmentState, ThreadBaseObject* pThisUNS
     // Assert that the thread hasn't been started yet.
     _ASSERTE(Thread::TS_Unstarted & thread->GetSnapshotState());
 
-    if ((g_pConfig != NULL) && !g_pConfig->LegacyApartmentInitPolicy())
+    Thread::ApartmentState as = thread->GetExplicitApartment();
+    if (as == Thread::AS_Unknown)
     {
-        Thread::ApartmentState as = thread->GetExplicitApartment();
-        if (as == Thread::AS_Unknown)
-        {
-            thread->SetApartment(Thread::AS_InMTA, TRUE);
-        }
+        thread->SetApartment(Thread::AS_InMTA, TRUE);
     }
 
     HELPER_METHOD_FRAME_END();
index 7c98317..8ba9600 100644 (file)
@@ -108,8 +108,6 @@ typedef DPTR(CONNID)   PTR_CONNID;
 
 // *** ICorRuntimeHost methods ***
 
-extern BOOL g_fWeOwnProcess;
-
 CorHost2::CorHost2()
 {
     LIMITED_METHOD_CONTRACT;
@@ -195,18 +193,7 @@ STDMETHODIMP CorHost2::Start()
             // So, if you want to do that, just make sure you are the first host to load the
             // specific version of CLR in memory AND start it.
             m_fFirstToLoadCLR = TRUE;
-            if (FastInterlockIncrement(&m_RefCount) != 1)
-            {
-            }
-            else
-            {
-                if (g_fWeOwnProcess)
-                {
-                    // Runtime is started by a managed exe.  Bump the ref-count, so that
-                    // matching Start/Stop does not stop runtime.
-                    FastInterlockIncrement(&m_RefCount);
-                }
-            }
+            FastInterlockIncrement(&m_RefCount);
         }
     }
 
index df74456..a54a6d5 100644 (file)
@@ -223,7 +223,6 @@ HRESULT EEConfig::Init()
 
     fLegacyNullReferenceExceptionPolicy = false;
     fLegacyUnhandledExceptionPolicy = false;
-    fLegacyApartmentInitPolicy = false;
     fLegacyComHierarchyVisibility = false;
     fLegacyComVTableLayout = false;
     fNewComVTableLayout = false;
index 6f290fa..a71873a 100644 (file)
@@ -317,7 +317,6 @@ public:
     bool LegacyNullReferenceExceptionPolicy(void)   const {LIMITED_METHOD_CONTRACT;  return fLegacyNullReferenceExceptionPolicy; }
     bool LegacyUnhandledExceptionPolicy(void)       const {LIMITED_METHOD_CONTRACT;  return fLegacyUnhandledExceptionPolicy; }
 
-    bool LegacyApartmentInitPolicy(void)            const {LIMITED_METHOD_CONTRACT;  return fLegacyApartmentInitPolicy; }
     bool LegacyComHierarchyVisibility(void)         const {LIMITED_METHOD_CONTRACT;  return fLegacyComHierarchyVisibility; }
     bool LegacyComVTableLayout(void)                const {LIMITED_METHOD_CONTRACT;  return fLegacyComVTableLayout; }
     bool NewComVTableLayout(void)                   const {LIMITED_METHOD_CONTRACT;  return fNewComVTableLayout; }
@@ -867,7 +866,6 @@ private: //----------------------------------------------------------------
     bool fLegacyCorruptedStateExceptionsPolicy;
 #endif // FEATURE_CORRUPTING_EXCEPTIONS
 
-    bool fLegacyApartmentInitPolicy;          // Old nondeterministic COM apartment initialization switch
     bool fLegacyComHierarchyVisibility;       // Old behavior allowing QIs for classes with invisible parents
     bool fLegacyComVTableLayout;              // Old behavior passing out IClassX interface for IUnknown and IDispatch.
     bool fNewComVTableLayout;                 // New behavior passing out Basic interface for IUnknown and IDispatch.