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"), "")
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);
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);
}
#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);
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();
}
#endif
-BOOL g_fWeOwnProcess = FALSE;
-
static LONG s_ActiveShutdownThreadCount = 0;
// ---------------------------------------------------------------------------
{
action = eRudeExitProcess;
}
- UINT exitCode;
- if (g_fWeOwnProcess)
- {
- exitCode = GetLatchedExitCode();
- }
- else
- {
- exitCode = HOST_E_EXITPROCESS_TIMEOUT;
- }
+
+ UINT exitCode = GetLatchedExitCode();
EEPolicy::HandleExitProcessFromEscalation(action, exitCode);
return 0;
}
#ifdef FEATURE_COMINTEROP
- if (!fIsDllUnloading && IsThreadInSTA())
+ if (!fIsDllUnloading && CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_FinalizeOnShutdown) && IsThreadInSTA())
{
// #STAShutDown
//
// 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();
// *** ICorRuntimeHost methods ***
-extern BOOL g_fWeOwnProcess;
-
CorHost2::CorHost2()
{
LIMITED_METHOD_CONTRACT;
// 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);
}
}
fLegacyNullReferenceExceptionPolicy = false;
fLegacyUnhandledExceptionPolicy = false;
- fLegacyApartmentInitPolicy = false;
fLegacyComHierarchyVisibility = false;
fLegacyComVTableLayout = false;
fNewComVTableLayout = false;
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; }
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.