From 21cfdb6f5bb8c596aa55cc50892be0bfabee5de3 Mon Sep 17 00:00:00 2001 From: Anirudh Agnihotry Date: Sat, 16 Dec 2017 14:50:09 -0800 Subject: [PATCH] Respect STA/MTAThread attributes (#15512) * Apartment state set for main method * Default apartment state is Unknown * Removed Extra validation of token * Removed legacy apartment code --- src/inc/clrconfigvalues.h | 1 - src/vm/appdomain.cpp | 39 ++------------------------------------- src/vm/appdomain.hpp | 2 +- src/vm/assembly.cpp | 15 +++++++++++++++ src/vm/comsynchronizable.cpp | 9 +++------ src/vm/eeconfig.cpp | 1 - src/vm/eeconfig.h | 2 -- 7 files changed, 21 insertions(+), 48 deletions(-) diff --git a/src/inc/clrconfigvalues.h b/src/inc/clrconfigvalues.h index b6e5342..6ddb566 100644 --- a/src/inc/clrconfigvalues.h +++ b/src/inc/clrconfigvalues.h @@ -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"), "") diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp index 07e3280..bab3f65 100644 --- a/src/vm/appdomain.cpp +++ b/src/vm/appdomain.cpp @@ -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); } diff --git a/src/vm/appdomain.hpp b/src/vm/appdomain.hpp index 8689ff8..ea1c471 100644 --- a/src/vm/appdomain.hpp +++ b/src/vm/appdomain.hpp @@ -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); diff --git a/src/vm/assembly.cpp b/src/vm/assembly.cpp index 32a7cd9..e93d2c3 100644 --- a/src/vm/assembly.cpp +++ b/src/vm/assembly.cpp @@ -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(); diff --git a/src/vm/comsynchronizable.cpp b/src/vm/comsynchronizable.cpp index 472ca34..1956121 100644 --- a/src/vm/comsynchronizable.cpp +++ b/src/vm/comsynchronizable.cpp @@ -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(); diff --git a/src/vm/eeconfig.cpp b/src/vm/eeconfig.cpp index df74456..a54a6d5 100644 --- a/src/vm/eeconfig.cpp +++ b/src/vm/eeconfig.cpp @@ -223,7 +223,6 @@ HRESULT EEConfig::Init() fLegacyNullReferenceExceptionPolicy = false; fLegacyUnhandledExceptionPolicy = false; - fLegacyApartmentInitPolicy = false; fLegacyComHierarchyVisibility = false; fLegacyComVTableLayout = false; fNewComVTableLayout = false; diff --git a/src/vm/eeconfig.h b/src/vm/eeconfig.h index 6f290fa..a71873a 100644 --- a/src/vm/eeconfig.h +++ b/src/vm/eeconfig.h @@ -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. -- 2.7.4