Revert "Respect STA/MTAThread attributes (#15512)"
authorJan Kotas <jkotas@microsoft.com>
Wed, 20 Dec 2017 15:52:29 +0000 (07:52 -0800)
committerJan Kotas <jkotas@microsoft.com>
Wed, 20 Dec 2017 15:52:29 +0000 (07:52 -0800)
This reverts commit 21cfdb6f5bb8c596aa55cc50892be0bfabee5de3.

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

index 6ddb566..b6e5342 100644 (file)
@@ -937,6 +937,7 @@ 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 bab3f65..07e3280 100644 (file)
@@ -3081,10 +3081,39 @@ Thread::ApartmentState SystemDomain::GetEntryPointThreadAptState(IMDInternalImpo
     return Thread::AS_Unknown;
 }
 
-void SystemDomain::SetThreadAptState (Thread::ApartmentState state)
+void SystemDomain::SetThreadAptState (IMDInternalImport* pScope, 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);
 
@@ -3093,8 +3122,14 @@ void SystemDomain::SetThreadAptState (Thread::ApartmentState state)
         Thread::ApartmentState pState = pThread->SetApartment(Thread::AS_InSTA, TRUE);
         _ASSERTE(pState == Thread::AS_InSTA);
     }
-    else if (state == Thread::AS_InMTA)
+    else if ((state == Thread::AS_InMTA) || (!fIsLegacy))
     {
+        // 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 ea1c471..8689ff8 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(Thread::ApartmentState state);
+    static void SetThreadAptState(IMDInternalImport* pScope, Thread::ApartmentState state);
 #endif
     static BOOL SetGlobalSharePolicyUsingAttribute(IMDInternalImport* pScope, mdMethodDef mdMethod);
 
index e93d2c3..32a7cd9 100644 (file)
@@ -1790,22 +1790,7 @@ 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 1956121..472ca34 100644 (file)
@@ -1109,10 +1109,13 @@ FCIMPL1(void, ThreadNative::StartupSetApartmentState, ThreadBaseObject* pThisUNS
     // Assert that the thread hasn't been started yet.
     _ASSERTE(Thread::TS_Unstarted & thread->GetSnapshotState());
 
-    Thread::ApartmentState as = thread->GetExplicitApartment();
-    if (as == Thread::AS_Unknown)
+    if ((g_pConfig != NULL) && !g_pConfig->LegacyApartmentInitPolicy())
     {
-        thread->SetApartment(Thread::AS_InMTA, TRUE);
+        Thread::ApartmentState as = thread->GetExplicitApartment();
+        if (as == Thread::AS_Unknown)
+        {
+            thread->SetApartment(Thread::AS_InMTA, TRUE);
+        }
     }
 
     HELPER_METHOD_FRAME_END();
index a54a6d5..df74456 100644 (file)
@@ -223,6 +223,7 @@ HRESULT EEConfig::Init()
 
     fLegacyNullReferenceExceptionPolicy = false;
     fLegacyUnhandledExceptionPolicy = false;
+    fLegacyApartmentInitPolicy = false;
     fLegacyComHierarchyVisibility = false;
     fLegacyComVTableLayout = false;
     fNewComVTableLayout = false;
index a71873a..6f290fa 100644 (file)
@@ -317,6 +317,7 @@ 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; }
@@ -866,6 +867,7 @@ 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.