From 31e22b200de37bd8005c650c90e2098e42201eec Mon Sep 17 00:00:00 2001 From: Anirudh Agnihotry Date: Thu, 28 Dec 2017 16:35:12 -0800 Subject: [PATCH] Recognize STA\MTA Attribute For Main Function (#15652) * Apartment state set for main method * g_fWeownprocess removed and CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_FinalizeOnShutdown) set --- src/inc/clrconfigvalues.h | 1 - src/vm/appdomain.cpp | 39 ++------------------------------------- src/vm/appdomain.hpp | 2 +- src/vm/assembly.cpp | 15 +++++++++++++++ src/vm/ceemain.cpp | 15 +++------------ src/vm/comsynchronizable.cpp | 9 +++------ src/vm/corhost.cpp | 15 +-------------- src/vm/eeconfig.cpp | 1 - src/vm/eeconfig.h | 2 -- 9 files changed, 25 insertions(+), 74 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/ceemain.cpp b/src/vm/ceemain.cpp index 8b44945..3f6492b 100644 --- a/src/vm/ceemain.cpp +++ b/src/vm/ceemain.cpp @@ -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 // 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/corhost.cpp b/src/vm/corhost.cpp index 7c98317..8ba9600 100644 --- a/src/vm/corhost.cpp +++ b/src/vm/corhost.cpp @@ -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); } } 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