diff options
Diffstat (limited to 'src/vm/corhost.cpp')
-rw-r--r-- | src/vm/corhost.cpp | 4376 |
1 files changed, 16 insertions, 4360 deletions
diff --git a/src/vm/corhost.cpp b/src/vm/corhost.cpp index 369d6fcfd7..75adbada94 100644 --- a/src/vm/corhost.cpp +++ b/src/vm/corhost.cpp @@ -19,7 +19,6 @@ #include "eeconfig.h" #include "dbginterface.h" #include "ceemain.h" -#include "rwlock.h" #include "hosting.h" #include "eepolicy.h" #include "clrex.h" @@ -27,7 +26,6 @@ #include "ipcmanagerinterface.h" #endif // FEATURE_IPCMAN #include "comcallablewrapper.h" -#include "hostexecutioncontext.h" #include "invokeutil.h" #include "appdomain.inl" #include "vars.hpp" @@ -50,10 +48,6 @@ #include "winrttypenameconverter.h" #endif -#if defined(FEATURE_APPX_BINDER) -#include "clrprivbinderappx.h" -#include "clrprivtypecachewinrt.h" -#endif GVAL_IMPL_INIT(DWORD, g_fHostConfig, 0); @@ -74,7 +68,7 @@ SVAL_IMPL_INIT(DWORD, CExecutionEngine, TlsIndex, TLS_OUT_OF_INDEXES); #endif -#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE) +#if defined(FEATURE_WINDOWSPHONE) SVAL_IMPL_INIT(ECustomDumpFlavor, CCLRErrorReportingManager, g_ECustomDumpFlavor, DUMP_FLAVOR_Default); #endif @@ -89,406 +83,17 @@ extern BOOL g_fEEHostedStartup; INT64 g_PauseTime; // Total time in millisecond the CLR has been paused Volatile<BOOL> g_IsPaused; // True if the runtime is paused (FAS) CLREventStatic g_ClrResumeEvent; // Event that is fired at FAS Resuming -#ifndef FEATURE_CORECLR -CLREventStatic g_PauseCompletedEvent; // Set when Pause has completed its work on another thread. -#endif -#if defined(FEATURE_CORECLR) extern BYTE g_rbTestKeyBuffer[]; -#endif - -#if !defined(FEATURE_CORECLR) -//****************************************************************************** -// <TODO>TODO: ICorThreadpool: Move this into a separate file CorThreadpool.cpp -// after the move to VBL </TODO> -//****************************************************************************** - -HRESULT STDMETHODCALLTYPE CorThreadpool::CorRegisterWaitForSingleObject(PHANDLE phNewWaitObject, - HANDLE hWaitObject, - WAITORTIMERCALLBACK Callback, - PVOID Context, - ULONG timeout, - BOOL executeOnlyOnce, - BOOL* pResult) -{ - CONTRACTL - { - DISABLED(NOTHROW); - GC_TRIGGERS; - MODE_ANY; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = E_UNEXPECTED; - - BEGIN_ENTRYPOINT_NOTHROW; - - ULONG flag = executeOnlyOnce ? WAIT_SINGLE_EXECUTION : 0; - *pResult = FALSE; - EX_TRY - { - *pResult = ThreadpoolMgr::RegisterWaitForSingleObject(phNewWaitObject, - hWaitObject, - Callback, - Context, - timeout, - flag); - - hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError()); - } - EX_CATCH - { - hr = GET_EXCEPTION()->GetHR(); - } - EX_END_CATCH(SwallowAllExceptions); - - END_ENTRYPOINT_NOTHROW; - - return hr; -} - - -HRESULT STDMETHODCALLTYPE CorThreadpool::CorBindIoCompletionCallback(HANDLE fileHandle, - LPOVERLAPPED_COMPLETION_ROUTINE callback) -{ - CONTRACTL - { - DISABLED(NOTHROW); - GC_TRIGGERS; - MODE_ANY; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = E_UNEXPECTED; - BEGIN_ENTRYPOINT_NOTHROW; - - BOOL ret = FALSE; - DWORD errCode = 0; - - EX_TRY - { - ret = ThreadpoolMgr::BindIoCompletionCallback(fileHandle,callback,0, errCode); - hr = (ret ? S_OK : HRESULT_FROM_WIN32(errCode)); - } - EX_CATCH - { - hr = GET_EXCEPTION()->GetHR(); - } - EX_END_CATCH(SwallowAllExceptions); - - END_ENTRYPOINT_NOTHROW; - - return hr; -} - - -HRESULT STDMETHODCALLTYPE CorThreadpool::CorUnregisterWait(HANDLE hWaitObject, - HANDLE CompletionEvent, - BOOL* pResult) -{ - CONTRACTL - { - DISABLED(NOTHROW); - GC_TRIGGERS; - MODE_ANY; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = E_UNEXPECTED; - - BEGIN_ENTRYPOINT_NOTHROW; - - *pResult = FALSE; - EX_TRY - { - - *pResult = ThreadpoolMgr::UnregisterWaitEx(hWaitObject,CompletionEvent); - hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError()); - } - EX_CATCH - { - hr = GET_EXCEPTION()->GetHR(); - } - EX_END_CATCH(SwallowAllExceptions); - - END_ENTRYPOINT_NOTHROW; - - return hr; - -} - -HRESULT STDMETHODCALLTYPE CorThreadpool::CorQueueUserWorkItem(LPTHREAD_START_ROUTINE Function, - PVOID Context,BOOL executeOnlyOnce, - BOOL* pResult ) -{ - CONTRACTL - { - DISABLED(NOTHROW); - GC_TRIGGERS; - MODE_ANY; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = E_UNEXPECTED; - BEGIN_ENTRYPOINT_NOTHROW; - - *pResult = FALSE; - EX_TRY - { - *pResult = ThreadpoolMgr::QueueUserWorkItem(Function,Context,QUEUE_ONLY); - hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError()); - } - EX_CATCH - { - hr = GET_EXCEPTION()->GetHR(); - } - EX_END_CATCH(SwallowAllExceptions); - - END_ENTRYPOINT_NOTHROW; - return hr; -} - -HRESULT STDMETHODCALLTYPE CorThreadpool::CorCallOrQueueUserWorkItem(LPTHREAD_START_ROUTINE Function, - PVOID Context, - BOOL* pResult ) -{ - CONTRACTL - { - DISABLED(NOTHROW); - GC_TRIGGERS; - MODE_ANY; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = E_UNEXPECTED; - BEGIN_ENTRYPOINT_NOTHROW; - *pResult = FALSE; - EX_TRY - { - *pResult = ThreadpoolMgr::QueueUserWorkItem(Function,Context,CALL_OR_QUEUE); - hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError()); - } - EX_CATCH - { - hr = GET_EXCEPTION()->GetHR(); - } - EX_END_CATCH(SwallowAllExceptions); - END_ENTRYPOINT_NOTHROW; - return hr; -} - - -HRESULT STDMETHODCALLTYPE CorThreadpool::CorCreateTimer(PHANDLE phNewTimer, - WAITORTIMERCALLBACK Callback, - PVOID Parameter, - DWORD DueTime, - DWORD Period, - BOOL* pResult) -{ - CONTRACTL - { - DISABLED(NOTHROW); - GC_TRIGGERS; - MODE_ANY; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = E_UNEXPECTED; - BEGIN_ENTRYPOINT_NOTHROW; - - *pResult = FALSE; - EX_TRY - { - *pResult = ThreadpoolMgr::CreateTimerQueueTimer(phNewTimer,Callback,Parameter,DueTime,Period,0); - hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError()); - } - EX_CATCH - { - hr = GET_EXCEPTION()->GetHR(); - } - EX_END_CATCH(SwallowAllExceptions); - - END_ENTRYPOINT_NOTHROW; - return hr; -} - - -HRESULT STDMETHODCALLTYPE CorThreadpool::CorDeleteTimer(HANDLE Timer, HANDLE CompletionEvent, BOOL* pResult) -{ - CONTRACTL - { - DISABLED(NOTHROW); - GC_TRIGGERS; - MODE_ANY; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = E_UNEXPECTED; - BEGIN_ENTRYPOINT_NOTHROW; - - *pResult = FALSE; - EX_TRY - { - *pResult = ThreadpoolMgr::DeleteTimerQueueTimer(Timer,CompletionEvent); - hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError()); - } - EX_CATCH - { - hr = GET_EXCEPTION()->GetHR(); - } - EX_END_CATCH(SwallowAllExceptions); - - END_ENTRYPOINT_NOTHROW; - return hr; -} - -HRESULT STDMETHODCALLTYPE CorThreadpool::CorChangeTimer(HANDLE Timer, - ULONG DueTime, - ULONG Period, - BOOL* pResult) -{ - CONTRACTL - { - DISABLED(NOTHROW); - GC_TRIGGERS; - MODE_ANY; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = E_UNEXPECTED; - BEGIN_ENTRYPOINT_NOTHROW; - - *pResult = FALSE; - EX_TRY - { - //CONTRACT_VIOLATION(ThrowsViolation); - *pResult = ThreadpoolMgr::ChangeTimerQueueTimer(Timer,DueTime,Period); - hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError()); - } - EX_CATCH - { - hr = GET_EXCEPTION()->GetHR(); - } - EX_END_CATCH(SwallowAllExceptions); - - END_ENTRYPOINT_NOTHROW; - return hr; -} - - -HRESULT STDMETHODCALLTYPE CorThreadpool::CorSetMaxThreads(DWORD MaxWorkerThreads, - DWORD MaxIOCompletionThreads) -{ - CONTRACTL - { - DISABLED(NOTHROW); - GC_TRIGGERS; - MODE_ANY; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = E_UNEXPECTED; - BEGIN_ENTRYPOINT_NOTHROW; - - BOOL result = FALSE; - EX_TRY - { - result = ThreadpoolMgr::SetMaxThreads(MaxWorkerThreads, MaxIOCompletionThreads); - hr = (result ? S_OK : E_FAIL); - } - EX_CATCH - { - hr = GET_EXCEPTION()->GetHR(); - } - EX_END_CATCH(SwallowAllExceptions); - - END_ENTRYPOINT_NOTHROW; - return hr; -} - -HRESULT STDMETHODCALLTYPE CorThreadpool::CorGetMaxThreads(DWORD *MaxWorkerThreads, - DWORD *MaxIOCompletionThreads) -{ - CONTRACTL - { - DISABLED(NOTHROW); - GC_TRIGGERS; - MODE_ANY; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = E_UNEXPECTED; - BEGIN_ENTRYPOINT_NOTHROW; - - BOOL result = FALSE; - EX_TRY - { - result = ThreadpoolMgr::GetMaxThreads(MaxWorkerThreads, MaxIOCompletionThreads); - hr = (result ? S_OK : E_FAIL); - } - EX_CATCH - { - hr = GET_EXCEPTION()->GetHR(); - } - EX_END_CATCH(SwallowAllExceptions); - - END_ENTRYPOINT_NOTHROW; - return hr; -} - -HRESULT STDMETHODCALLTYPE CorThreadpool::CorGetAvailableThreads(DWORD *AvailableWorkerThreads, - DWORD *AvailableIOCompletionThreads) -{ - CONTRACTL - { - DISABLED(NOTHROW); - GC_TRIGGERS; - MODE_ANY; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = E_UNEXPECTED; - BEGIN_ENTRYPOINT_NOTHROW; - - BOOL result = FALSE; - EX_TRY - { - result = ThreadpoolMgr::GetAvailableThreads(AvailableWorkerThreads, AvailableIOCompletionThreads); - hr = (result ? S_OK : E_FAIL); - } - EX_CATCH - { - hr = GET_EXCEPTION()->GetHR(); - } - EX_END_CATCH(SwallowAllExceptions); - - END_ENTRYPOINT_NOTHROW; - return hr; -} -#endif // !defined(FEATURE_CORECLR) //*************************************************************************** ULONG CorRuntimeHostBase::m_Version = 0; -#ifdef FEATURE_INCLUDE_ALL_INTERFACES -static CCLRDebugManager s_CLRDebugManager; -#endif // FEATURE_INCLUDE_ALL_INTERFACES -#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE) +#if defined(FEATURE_WINDOWSPHONE) CCLRErrorReportingManager g_CLRErrorReportingManager; -#endif // defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE) +#endif // defined(FEATURE_WINDOWSPHONE) #ifdef FEATURE_IPCMAN static CCLRSecurityAttributeManager s_CLRSecurityAttributeManager; @@ -498,270 +103,16 @@ static CCLRSecurityAttributeManager s_CLRSecurityAttributeManager; typedef DPTR(CONNID) PTR_CONNID; -#ifdef FEATURE_INCLUDE_ALL_INTERFACES -// Hash table to keep track <connection, name> for SQL fiber support -class ConnectionNameTable : CHashTableAndData<CNewDataNoThrow> -{ - friend class CCLRDebugManager; -public: - - // Key to match is connection ID. - // Returns true if the given HASHENTRY has the same key as the requested key. - BOOL Cmp(SIZE_T requestedKey, const HASHENTRY * pEntry) - { - SUPPORTS_DAC; - LIMITED_METHOD_CONTRACT; - STATIC_CONTRACT_SO_TOLERANT; - - CONNID keyRequested = (CONNID)requestedKey; - CONNID keySearch = dac_cast<PTR_ConnectionNameHashEntry>(pEntry)->m_dwConnectionId; - return keyRequested != keySearch; - } - - // Hash function - ULONG Hash(CONNID dwConnectionId) - { - SUPPORTS_DAC; - LIMITED_METHOD_CONTRACT; - - return (ULONG)(dwConnectionId); - } - -#ifndef DACCESS_COMPILE - // constructor - ConnectionNameTable( - ULONG iBuckets) : // # of chains we are hashing into. - CHashTableAndData<CNewDataNoThrow>(iBuckets) - {LIMITED_METHOD_CONTRACT;} - - // destructor - ~ConnectionNameTable() - { - CONTRACTL - { - if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);} - NOTHROW; - } - CONTRACTL_END; - HASHFIND hashFind; - ConnectionNameHashEntry *pNameEntry; - - pNameEntry = (ConnectionNameHashEntry *)FindFirstEntry(&hashFind); - while (pNameEntry != NULL) - { - if (pNameEntry->m_pwzName) - { - delete pNameEntry->m_pwzName; - pNameEntry->m_pwzName = NULL; - } - - if (pNameEntry->m_CLRTaskCount != 0) - { - _ASSERTE(pNameEntry->m_ppCLRTaskArray != NULL); - for (UINT i = 0; i < pNameEntry->m_CLRTaskCount; i++) - { - pNameEntry->m_ppCLRTaskArray[i]->Release(); - } - delete [] pNameEntry->m_ppCLRTaskArray; - pNameEntry->m_ppCLRTaskArray = NULL; - pNameEntry->m_CLRTaskCount = 0; - } - pNameEntry = (ConnectionNameHashEntry *)FindNextEntry(&hashFind); - } - } - - // Add a new connection into hash table. - // This function does not throw but return NULL when memory allocation fails. - ConnectionNameHashEntry *AddConnection( - CONNID dwConnectionId, - __in_z WCHAR *pwzName) // We should review this in the future. This API is - // public and callable by a host. This SAL annotation - // is the best we can do now. - { - CONTRACTL - { - GC_NOTRIGGER; - NOTHROW; - } - CONTRACTL_END; - - ULONG iHash = Hash(dwConnectionId); - - size_t len = wcslen(pwzName) + 1; - WCHAR *pConnName = new (nothrow) WCHAR[len]; - if (pConnName == NULL) - return NULL; - - ConnectionNameHashEntry *pRecord = (ConnectionNameHashEntry *)Add(iHash); - if (pRecord) - { - pRecord->m_dwConnectionId = dwConnectionId; - pRecord->m_pwzName = pConnName; - wcsncpy_s(pRecord->m_pwzName, len, pwzName, len); - pRecord->m_CLRTaskCount = 0; - pRecord->m_ppCLRTaskArray = NULL; - } - else - { - if (pConnName) - delete [] pConnName; - } - - return pRecord; - } - - // Delete a hash entry given a connection id - void DeleteConnection(CONNID dwConnectionId) - { - CONTRACTL - { - GC_NOTRIGGER; - NOTHROW; - } - CONTRACTL_END; - - ULONG iHash; - iHash = Hash(dwConnectionId); - ConnectionNameHashEntry * pRecord = - reinterpret_cast<ConnectionNameHashEntry *>(Find(iHash, (SIZE_T)dwConnectionId)); - if (pRecord == NULL) - { - return; - } - - _ASSERTE(pRecord->m_CLRTaskCount == 0 && pRecord->m_ppCLRTaskArray == NULL); - if (pRecord->m_pwzName) - { - delete pRecord->m_pwzName; - pRecord->m_pwzName = NULL; - } - Delete(iHash, (HASHENTRY *)pRecord); - } - - // return NULL if the given connection id cannot be found. - ConnectionNameHashEntry *FindConnection(CONNID dwConnectionId) - { - CONTRACTL - { - GC_NOTRIGGER; - NOTHROW; - } - CONTRACTL_END; - - ULONG iHash; - iHash = Hash(dwConnectionId); - return reinterpret_cast<ConnectionNameHashEntry *>(Find(iHash, (SIZE_T)dwConnectionId)); - } -#endif // !DAC -}; -#endif //FEATURE_INCLUDE_ALL_INTERFACES // Keep track connection id and name -#ifdef FEATURE_INCLUDE_ALL_INTERFACES -SPTR_IMPL(ConnectionNameTable, CCLRDebugManager, m_pConnectionNameHash); -CrstStatic CCLRDebugManager::m_lockConnectionNameTable; -#endif // FEATURE_INCLUDE_ALL_INTERFACES #ifndef DACCESS_COMPILE -#if !defined(FEATURE_CORECLR) // simple hosting -//***************************************************************************** -// ICorRuntimeHost -//***************************************************************************** -extern BOOL g_singleVersionHosting; - -// *** ICorRuntimeHost methods *** -// Returns an object for configuring the runtime prior to -// it starting. If the runtime has been initialized this -// routine returns an error. See ICorConfiguration. -HRESULT CorHost::GetConfiguration(ICorConfiguration** pConfiguration) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - ENTRY_POINT; - } - CONTRACTL_END; - HRESULT hr=E_FAIL; - BEGIN_ENTRYPOINT_NOTHROW; - if (CorHost::GetHostVersion() != 1) - { - hr=HOST_E_INVALIDOPERATION; - } - else - if (!pConfiguration) - hr= E_POINTER; - else - if (!m_Started) - { - *pConfiguration = (ICorConfiguration *) this; - AddRef(); - hr=S_OK; - } - END_ENTRYPOINT_NOTHROW; - // Cannot obtain configuration after the runtime is started - return hr; -} - -STDMETHODIMP CorHost::Start(void) -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr; - BEGIN_ENTRYPOINT_NOTHROW; - hr = CorRuntimeHostBase::Start(); - - END_ENTRYPOINT_NOTHROW; - - if (hr == S_FALSE) - { - // This is to keep v1 behavior. - hr = S_OK; - } - return(hr); -} -#endif // !defined(FEATURE_CORECLR) // *** ICorRuntimeHost methods *** -#ifndef FEATURE_CORECLR -// Returns an object for configuring the runtime prior to -// it starting. If the runtime has been initialized this -// routine returns an error. See ICorConfiguration. -HRESULT CorHost2::GetConfiguration(ICorConfiguration** pConfiguration) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - ENTRY_POINT; - } - CONTRACTL_END; - - if (!pConfiguration) - return E_POINTER; - HRESULT hr=E_FAIL; - BEGIN_ENTRYPOINT_NOTHROW; - if (!m_Started) - { - *pConfiguration = (ICorConfiguration *) this; - AddRef(); - hr=S_OK; - } - END_ENTRYPOINT_NOTHROW; - // Cannot obtain configuration after the runtime is started - return hr; -} -#endif // FEATURE_CORECLR extern BOOL g_fWeOwnProcess; @@ -769,11 +120,9 @@ CorHost2::CorHost2() { LIMITED_METHOD_CONTRACT; -#ifdef FEATURE_CORECLR m_fStarted = FALSE; m_fFirstToLoadCLR = FALSE; m_fAppDomainCreated = FALSE; -#endif // FEATURE_CORECLR } static DangerousNonHostedSpinLock lockOnlyOneToInvokeStart; @@ -791,7 +140,6 @@ STDMETHODIMP CorHost2::Start() BEGIN_ENTRYPOINT_NOTHROW; -#ifdef FEATURE_CORECLR // Ensure that only one thread at a time gets in here DangerousNonHostedSpinLockHolder lockHolder(&lockOnlyOneToInvokeStart); @@ -821,7 +169,6 @@ STDMETHODIMP CorHost2::Start() } } else -#endif // FEATURE_CORECLR { // Using managed C++ libraries, its possible that when the runtime is already running, // MC++ will use CorBindToRuntimeEx to make callbacks into specific appdomain of its @@ -842,7 +189,6 @@ STDMETHODIMP CorHost2::Start() hr = CorRuntimeHostBase::Start(); if (SUCCEEDED(hr)) { -#ifdef FEATURE_CORECLR // Set our flag that this host invoked the Start method. m_fStarted = TRUE; @@ -855,7 +201,6 @@ 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; -#endif // FEATURE_CORECLR if (FastInterlockIncrement(&m_RefCount) != 1) { } @@ -901,21 +246,6 @@ HRESULT CorRuntimeHostBase::Start() return hr; } -#if !defined(FEATURE_CORECLR) // simple hosting -HRESULT CorHost::Stop() -{ - CONTRACTL - { - NOTHROW; - ENTRY_POINT; - if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);} - } - CONTRACTL_END; - - // This must remain this way (that is doing nothing) for backwards compat reasons. - return S_OK; -} -#endif // !defined(FEATURE_CORECLR) HRESULT CorHost2::Stop() { @@ -933,7 +263,6 @@ HRESULT CorHost2::Stop() HRESULT hr=S_OK; BEGIN_ENTRYPOINT_NOTHROW; -#ifdef FEATURE_CORECLR // Is this host eligible to invoke the Stop method? if ((!m_fStarted) && (!m_fFirstToLoadCLR)) { @@ -944,28 +273,21 @@ HRESULT CorHost2::Stop() hr = HOST_E_CLRNOTAVAILABLE; } else -#endif // FEATURE_CORECLR { while (TRUE) { LONG refCount = m_RefCount; if (refCount == 0) { - #ifdef FEATURE_CORECLR hr = HOST_E_CLRNOTAVAILABLE; - #else // !FEATURE_CORECLR - hr= E_UNEXPECTED; - #endif // FEATURE_CORECLR break; } else if (FastInterlockCompareExchange(&m_RefCount, refCount - 1, refCount) == refCount) { - #ifdef FEATURE_CORECLR // Indicate that we have got a Stop for a corresponding Start call from the // Host. Semantically, CoreCLR has stopped for them. m_fStarted = FALSE; - #endif // FEATURE_CORECLR if (refCount > 1) { @@ -979,125 +301,12 @@ HRESULT CorHost2::Stop() } } } -#ifndef FEATURE_CORECLR - if (hr==S_OK) - { - EPolicyAction action = GetEEPolicy()->GetDefaultAction(OPR_ProcessExit, NULL); - if (action > eExitProcess) - { - g_fFastExitProcess = 1; - } - EEShutDown(FALSE); - } -#endif // FEATURE_CORECLR END_ENTRYPOINT_NOTHROW; -#ifndef FEATURE_CORECLR - if (hr == S_OK) - { - if (m_HostControl) - { - m_HostControl->Release(); - m_HostControl = NULL; - } - } -#endif // FEATURE_CORECLR - - return hr; -} - -#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR) - -// Creates a domain in the runtime. The identity array is -// a pointer to an array TYPE containing IIdentity objects defining -// the security identity. -HRESULT CorRuntimeHostBase::CreateDomain(LPCWSTR pwzFriendlyName, - IUnknown* pIdentityArray, // Optional - IUnknown ** pAppDomain) -{ - WRAPPER_NO_CONTRACT; - STATIC_CONTRACT_ENTRY_POINT; - - return CreateDomainEx(pwzFriendlyName, - NULL, - NULL, - pAppDomain); -} - - -// Returns the default domain. -HRESULT CorRuntimeHostBase::GetDefaultDomain(IUnknown ** pAppDomain) -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_PREEMPTIVE; - ENTRY_POINT; - } CONTRACTL_END; - - HRESULT hr = E_UNEXPECTED; - if (!g_fEEStarted) - return hr; - - if( pAppDomain == NULL) - return E_POINTER; - - BEGIN_ENTRYPOINT_NOTHROW; - - BEGIN_EXTERNAL_ENTRYPOINT(&hr); - { - GCX_COOP_THREAD_EXISTS(GET_THREAD()); - - if (SystemDomain::System()) { - AppDomain* pCom = SystemDomain::System()->DefaultDomain(); - if(pCom) - hr = pCom->GetComIPForExposedObject(pAppDomain); - } - - } - END_EXTERNAL_ENTRYPOINT; - END_ENTRYPOINT_NOTHROW; return hr; } -// Returns the default domain. -HRESULT CorRuntimeHostBase::CurrentDomain(IUnknown ** pAppDomain) -{ - CONTRACTL - { - NOTHROW; - MODE_PREEMPTIVE; - ENTRY_POINT; - if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);} - } - CONTRACTL_END; - - HRESULT hr = E_UNEXPECTED; - if (!g_fEEStarted) - return hr; - - if( pAppDomain == NULL) return E_POINTER; - - BEGIN_ENTRYPOINT_NOTHROW; - - BEGIN_EXTERNAL_ENTRYPOINT(&hr); - { - GCX_COOP_THREAD_EXISTS(GET_THREAD()); - - AppDomain* pCom = ::GetAppDomain(); - if(pCom) - hr = pCom->GetComIPForExposedObject(pAppDomain); - - } - END_EXTERNAL_ENTRYPOINT; - END_ENTRYPOINT_NOTHROW; - - return hr; -}; - -#endif // FEATURE_COMINTEROP && !FEATURE_CORECLR HRESULT CorHost2::GetCurrentAppDomainId(DWORD *pdwAppDomainId) { @@ -1113,9 +322,7 @@ HRESULT CorHost2::GetCurrentAppDomainId(DWORD *pdwAppDomainId) // We use CanRunManagedCode() instead of IsRuntimeActive() because this allows us // to specify test using the form that does not trigger a GC. if (!(g_fEEStarted && CanRunManagedCode(LoaderLockCheck::None)) -#ifdef FEATURE_CORECLR || !m_fStarted -#endif ) { return HOST_E_CLRNOTAVAILABLE; @@ -1154,64 +361,9 @@ HRESULT CorHost2::ExecuteApplication(LPCWSTR pwzAppFullName, LPCWSTR *ppwzActivationData, int *pReturnValue) { -#ifndef FEATURE_CORECLR - // This API should not be called when the EE has already been started. - HRESULT hr = E_UNEXPECTED; - if (g_fEEStarted) - return hr; - - // - // We will let unhandled exceptions in the activated application - // propagate all the way up, so that ClickOnce semi-trusted apps - // can participate in the Dr Watson program, etc... - // - - CONTRACTL { - THROWS; - ENTRY_POINT; - } - CONTRACTL_END; - - if (!pwzAppFullName) - IfFailGo(E_POINTER); - - // Set the information about the application to execute. - CorCommandLine::m_pwszAppFullName = (LPWSTR) pwzAppFullName; - CorCommandLine::m_dwManifestPaths = dwManifestPaths; - CorCommandLine::m_ppwszManifestPaths = (LPWSTR*) ppwzManifestPaths; - CorCommandLine::m_dwActivationData = dwActivationData; - CorCommandLine::m_ppwszActivationData = (LPWSTR*) ppwzActivationData; - - // Start up the EE. - IfFailGo(Start()); - - Thread *pThread; - pThread = GetThread(); - if (pThread == NULL) - pThread = SetupThreadNoThrow(&hr); - if (pThread == NULL) - goto ErrExit; - - _ASSERTE (!pThread->PreemptiveGCDisabled()); - - hr = S_OK; - - BEGIN_ENTRYPOINT_THROWS_WITH_THREAD(pThread); - ENTER_DOMAIN_PTR(SystemDomain::System()->DefaultDomain(),ADV_DEFAULTAD) - - SystemDomain::ActivateApplication(pReturnValue); - - END_DOMAIN_TRANSITION; - END_ENTRYPOINT_THROWS_WITH_THREAD; - -ErrExit: - return hr; -#else // FEATURE_CORECLR return E_NOTIMPL; -#endif } -#ifdef FEATURE_CORECLR /* * This method processes the arguments sent to the host which are then used * to invoke the main method. @@ -1363,7 +515,6 @@ ErrExit: return hr; } -#endif HRESULT CorHost2::ExecuteInDefaultAppDomain(LPCWSTR pwzAssemblyPath, LPCWSTR pwzTypeName, @@ -1380,98 +531,15 @@ HRESULT CorHost2::ExecuteInDefaultAppDomain(LPCWSTR pwzAssemblyPath, // No point going further if the runtime is not running... if (!IsRuntimeActive() -#ifdef FEATURE_CORECLR || !m_fStarted -#endif ) { return HOST_E_CLRNOTAVAILABLE; } -#ifndef FEATURE_CORECLR - if(! (pwzAssemblyPath && pwzTypeName && pwzMethodName) ) - return E_POINTER; - - HRESULT hr = S_OK; - - BEGIN_ENTRYPOINT_NOTHROW; - - Thread *pThread = GetThread(); - if (pThread == NULL) - { - pThread = SetupThreadNoThrow(&hr); - if (pThread == NULL) - { - goto ErrExit; - } - } - - _ASSERTE (!pThread->PreemptiveGCDisabled()); - - EX_TRY - { - ENTER_DOMAIN_PTR(SystemDomain::System()->DefaultDomain(),ADV_DEFAULTAD) - - INSTALL_UNWIND_AND_CONTINUE_HANDLER; - - Assembly *pAssembly = AssemblySpec::LoadAssembly(pwzAssemblyPath); - - SString szTypeName(pwzTypeName); - StackScratchBuffer buff1; - const char* szTypeNameUTF8 = szTypeName.GetUTF8(buff1); - MethodTable *pMT = ClassLoader::LoadTypeByNameThrowing(pAssembly, - NULL, - szTypeNameUTF8).AsMethodTable(); - - SString szMethodName(pwzMethodName); - StackScratchBuffer buff; - const char* szMethodNameUTF8 = szMethodName.GetUTF8(buff); - MethodDesc *pMethodMD = MemberLoader::FindMethod(pMT, szMethodNameUTF8, &gsig_SM_Str_RetInt); - - if (!pMethodMD) - { - hr = COR_E_MISSINGMETHOD; - } - else - { - GCX_COOP(); - - MethodDescCallSite method(pMethodMD); - - STRINGREF sref = NULL; - GCPROTECT_BEGIN(sref); - - if (pwzArgument) - sref = StringObject::NewString(pwzArgument); - - ARG_SLOT MethodArgs[] = - { - ObjToArgSlot(sref) - }; - DWORD retval = method.Call_RetI4(MethodArgs); - if (pReturnValue) - { - *pReturnValue = retval; - } - - GCPROTECT_END(); - } - - UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; - END_DOMAIN_TRANSITION; - } - EX_CATCH_HRESULT(hr); - -ErrExit: - - END_ENTRYPOINT_NOTHROW; - - return hr; -#else // FEATURE_CORECLR // Ensure that code is not loaded in the Default AppDomain return HOST_E_INVALIDOPERATION; -#endif } HRESULT ExecuteInAppDomainHelper(FExecuteInAppDomainCallback pCallback, @@ -1496,22 +564,18 @@ HRESULT CorHost2::ExecuteInAppDomain(DWORD dwAppDomainId, // No point going further if the runtime is not running... if (!IsRuntimeActive() -#ifdef FEATURE_CORECLR || !m_fStarted -#endif // FEATURE_CORECLR ) { return HOST_E_CLRNOTAVAILABLE; } -#ifdef FEATURE_CORECLR if(!(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN)) { // Ensure that code is not loaded in the Default AppDomain if (dwAppDomainId == DefaultADID) return HOST_E_INVALIDOPERATION; } -#endif // FEATURE_CORECLR // Moved this here since no point validating the pointer // if the basic checks [above] fail @@ -1555,9 +619,6 @@ HRESULT CorHost2::_CreateAppDomain( int nProperties, LPCWSTR* pPropertyNames, LPCWSTR* pPropertyValues, -#if !defined(FEATURE_CORECLR) - ICLRPrivBinder* pBinder, -#endif DWORD* pAppDomainID) { CONTRACTL @@ -1570,13 +631,11 @@ HRESULT CorHost2::_CreateAppDomain( HRESULT hr=S_OK; -#ifdef FEATURE_CORECLR //cannot call the function more than once when single appDomain is allowed if (m_fAppDomainCreated && (m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN)) { return HOST_E_INVALIDOPERATION; } -#endif //normalize empty strings EMPTY_STRING_TO_NULL(wszFriendlyName); @@ -1586,10 +645,8 @@ HRESULT CorHost2::_CreateAppDomain( if(pAppDomainID==NULL) return E_POINTER; -#ifdef FEATURE_CORECLR if (!m_fStarted) return HOST_E_INVALIDOPERATION; -#endif // FEATURE_CORECLR if(wszFriendlyName == NULL) return E_INVALIDARG; @@ -1604,26 +661,22 @@ HRESULT CorHost2::_CreateAppDomain( AppDomainCreationHolder<AppDomain> pDomain; -#ifdef FEATURE_CORECLR // If StartupFlag specifies single appDomain then return the default domain instead of creating new one if(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN) { pDomain.Assign(SystemDomain::System()->DefaultDomain()); } else -#endif { AppDomain::CreateUnmanagedObject(pDomain); } ETW::LoaderLog::DomainLoad(pDomain, (LPWSTR)wszFriendlyName); -#ifdef FEATURE_CORECLR if (dwFlags & APPDOMAIN_IGNORE_UNHANDLED_EXCEPTIONS) { pDomain->SetIgnoreUnhandledExceptions(); } -#endif // FEATURE_CORECLR if (dwFlags & APPDOMAIN_SECURITY_FORBID_CROSSAD_REVERSE_PINVOKE) pDomain->SetReversePInvokeCannotEnter(); @@ -1631,10 +684,6 @@ HRESULT CorHost2::_CreateAppDomain( if (dwFlags & APPDOMAIN_FORCE_TRIVIAL_WAIT_OPERATIONS) pDomain->SetForceTrivialWaitOperations(); -#if !defined(FEATURE_CORECLR) - if (pBinder != NULL) - pDomain->SetLoadContextHostBinder(pBinder); -#endif #ifdef PROFILING_SUPPORTED EX_TRY @@ -1689,12 +738,8 @@ HRESULT CorHost2::_CreateAppDomain( args[1]=ObjToArgSlot(NULL); args[2]=ObjToArgSlot(NULL); args[3]=ObjToArgSlot(NULL); -#ifdef FEATURE_CORECLR //CoreCLR shouldn't have dependencies on parent app domain. args[4]=ObjToArgSlot(NULL); -#else - args[4]=PtrToArgSlot(GetAppDomain()->GetSecurityDescriptor()); -#endif //FEATURE_CORECLR args[5]=ObjToArgSlot(_gc.sandboxName); args[6]=ObjToArgSlot(_gc.propertyNames); args[7]=ObjToArgSlot(_gc.propertyValues); @@ -1707,12 +752,6 @@ HRESULT CorHost2::_CreateAppDomain( PTRARRAYREF handleArrayObj = (PTRARRAYREF) ObjectToOBJECTREF(_gc.setupInfo); _gc.adSetup = ObjectToOBJECTREF(handleArrayObj->GetAt(1)); -#ifndef FEATURE_CORECLR - // We need to setup domain sorting before any other managed code runs in the domain, since that code - // could end up caching data based on the sorting mode of the domain. - pDomain->InitializeSorting(&_gc.adSetup); - pDomain->InitializeHashing(&_gc.adSetup); -#endif pDomain->DoSetup(&_gc.setupInfo); @@ -1722,13 +761,11 @@ HRESULT CorHost2::_CreateAppDomain( *pAppDomainID=pDomain->GetId().m_dwId; -#ifdef FEATURE_CORECLR // If StartupFlag specifies single appDomain then set the flag that appdomain has already been created if(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN) { m_fAppDomainCreated = TRUE; } -#endif } #ifdef PROFILING_SUPPORTED EX_HOOK @@ -1798,7 +835,6 @@ HRESULT CorHost2::_CreateDelegate( if(wszMethodName == NULL) return E_INVALIDARG; -#ifdef FEATURE_CORECLR if (!m_fStarted) return HOST_E_INVALIDOPERATION; @@ -1808,7 +844,6 @@ HRESULT CorHost2::_CreateDelegate( if (appDomainID == DefaultADID) return HOST_E_INVALIDOPERATION; } -#endif BEGIN_ENTRYPOINT_NOTHROW; @@ -1856,11 +891,9 @@ HRESULT CorHost2::_CreateDelegate( if (pMD==NULL || !pMD->IsStatic() || pMD->ContainsGenericVariables()) ThrowHR(COR_E_MISSINGMETHOD); -#ifdef FEATURE_CORECLR // the target method must be decorated with AllowReversePInvokeCallsAttribute if (!COMDelegate::IsMethodAllowedToSinkReversePInvoke(pMD)) ThrowHR(COR_E_SECURITY); -#endif UMEntryThunk *pUMEntryThunk = GetAppDomain()->GetUMEntryThunkCache()->GetUMEntryThunk(pMD); *fnPtr = (INT_PTR)pUMEntryThunk->GetCode(); @@ -1874,7 +907,6 @@ HRESULT CorHost2::_CreateDelegate( return hr; } -#ifdef FEATURE_CORECLR HRESULT CorHost2::CreateAppDomainWithManager( LPCWSTR wszFriendlyName, DWORD dwFlags, @@ -1957,70 +989,7 @@ HRESULT CorHost2::SetStartupFlags(STARTUP_FLAGS flag) return S_OK; } -#endif //FEATURE_CORECLR - -#ifndef FEATURE_CORECLR -void PauseOneAppDomain(AppDomainIterator* pi) -{ - CONTRACTL - { - NOTHROW; - MODE_COOPERATIVE; - GC_TRIGGERS; - } - CONTRACTL_END; - - EX_TRY { - ENTER_DOMAIN_PTR(pi->GetDomain(),ADV_ITERATOR); - - MethodDescCallSite(METHOD__APP_DOMAIN__PAUSE).Call(NULL); - - END_DOMAIN_TRANSITION; - } EX_CATCH { - } EX_END_CATCH(SwallowAllExceptions); -} - -void ResumeOneAppDomain(AppDomainIterator* pi) -{ - CONTRACTL - { - NOTHROW; - MODE_COOPERATIVE; - GC_TRIGGERS; - } - CONTRACTL_END; - - EX_TRY { - ENTER_DOMAIN_PTR(pi->GetDomain(),ADV_ITERATOR); - - MethodDescCallSite(METHOD__APP_DOMAIN__RESUME).Call(NULL); - - END_DOMAIN_TRANSITION; - } EX_CATCH { - } EX_END_CATCH(SwallowAllExceptions); -} - -// see comments in SuspendEEFromPause -DWORD WINAPI SuspendAndResumeForPause(LPVOID arg) -{ - CONTRACTL - { - NOTHROW; - MODE_ANY; - GC_TRIGGERS; - } - CONTRACTL_END; - - ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_OTHER); - - g_PauseCompletedEvent.Set(); - g_ClrResumeEvent.Wait(INFINITE, FALSE); - - ThreadSuspend::RestartEE(FALSE, TRUE); - return 0; -} -#endif // !FEATURE_CORECLR HRESULT SuspendEEForPause() { @@ -2034,33 +1003,9 @@ HRESULT SuspendEEForPause() HRESULT hr = S_OK; -#ifdef FEATURE_CORECLR // In CoreCLR, we always resume from the same thread that paused. So we can simply suspend the EE from this thread, // knowing we'll restart from the same thread. ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_OTHER); -#else - // In the CLR, we can resume from a different thread than the one that paused. We can't call SuspendEE directly, - // because we can't call RestartEE from another thread. So we queue a workitem to the ThreadPool to call SuspendEE - // and ResumeEE on our behalf. - - EX_TRY - { - if (!ThreadpoolMgr::QueueUserWorkItem(SuspendAndResumeForPause, NULL, QUEUE_ONLY)) - { - hr = HRESULT_FROM_GetLastError(); - } - else - { - // wait for SuspendEE to complete before returning. - g_PauseCompletedEvent.Wait(INFINITE,FALSE); - } - } - EX_CATCH - { - hr = GET_EXCEPTION()->GetHR(); - } - EX_END_CATCH(SwallowAllExceptions); -#endif return hr; } @@ -2076,12 +1021,7 @@ HRESULT RestartEEFromPauseAndSetResumeEvent() CONTRACTL_END; // see comments in SuspendEEFromPause -#ifdef FEATURE_CORECLR ThreadSuspend::RestartEE(FALSE, TRUE); -#else - // setting the resume event below will restart the EE as well. We don't wait for the restart - // to complete, because we'll sync with it next time we go to cooperative mode. -#endif _ASSERTE(g_ClrResumeEvent.IsValid()); g_ClrResumeEvent.Set(); @@ -2111,10 +1051,6 @@ HRESULT CorExecutionManager::Pause(DWORD dwAppDomainId, DWORD dwFlags) HRESULT hr = S_OK; -#ifndef FEATURE_CORECLR - if (!IsRuntimeActive()) - return HOST_E_CLRNOTAVAILABLE; -#endif if(g_IsPaused) return E_FAIL; @@ -2126,12 +1062,6 @@ HRESULT CorExecutionManager::Pause(DWORD dwAppDomainId, DWORD dwFlags) else g_ClrResumeEvent.Reset(); -#ifndef FEATURE_CORECLR - if (!g_PauseCompletedEvent.IsValid()) - g_PauseCompletedEvent.CreateManualEvent(FALSE); - else - g_PauseCompletedEvent.Reset(); -#endif } EX_CATCH_HRESULT(hr); @@ -2142,20 +1072,6 @@ HRESULT CorExecutionManager::Pause(DWORD dwAppDomainId, DWORD dwFlags) m_dwFlags = dwFlags; -#ifndef FEATURE_CORECLR - if ((m_dwFlags & PAUSE_APP_DOMAINS) != 0) - { - Thread* pThread = SetupThreadNoThrow(&hr); - if (pThread != NULL) - { - GCX_COOP_THREAD_EXISTS(pThread); - - AppDomainIterator ai(/*bOnlyActive:*/ TRUE); - while (ai.Next()) - PauseOneAppDomain(&ai); - } - } -#endif if (SUCCEEDED(hr)) { @@ -2185,15 +1101,10 @@ HRESULT CorExecutionManager::Resume(DWORD dwAppDomainId) HRESULT hr = S_OK; -#ifndef FEATURE_CORECLR - if (!IsRuntimeActive()) - return HOST_E_CLRNOTAVAILABLE; -#endif if(!g_IsPaused) return E_FAIL; -#ifdef FEATURE_CORECLR // GCThread is the thread that did the Pause. Resume should also happen on that same thread Thread *pThread = GetThread(); if(pThread != ThreadSuspend::GetSuspensionThread()) @@ -2201,7 +1112,6 @@ HRESULT CorExecutionManager::Resume(DWORD dwAppDomainId) _ASSERTE(!"HOST BUG: The same thread that did Pause should do the Resume"); return E_FAIL; } -#endif BEGIN_ENTRYPOINT_NOTHROW; @@ -2215,23 +1125,6 @@ HRESULT CorExecutionManager::Resume(DWORD dwAppDomainId) hr = RestartEEFromPauseAndSetResumeEvent(); -#ifndef FEATURE_CORECLR - if (SUCCEEDED(hr)) - { - if ((m_dwFlags & PAUSE_APP_DOMAINS) != 0) - { - Thread* pThread = SetupThreadNoThrow(&hr); - if (pThread != NULL) - { - GCX_COOP_THREAD_EXISTS(pThread); - - AppDomainIterator ai(/*bOnlyActive:*/ TRUE); - while (ai.Next()) - ResumeOneAppDomain(&ai); - } - } - } -#endif END_ENTRYPOINT_NOTHROW; @@ -2241,7 +1134,6 @@ HRESULT CorExecutionManager::Resume(DWORD dwAppDomainId) #endif //!DACCESS_COMPILE -#ifdef FEATURE_CORECLR #ifndef DACCESS_COMPILE SVAL_IMPL(STARTUP_FLAGS, CorHost2, m_dwStartupFlags = STARTUP_CONCURRENT_GC); #else @@ -2252,347 +1144,9 @@ STARTUP_FLAGS CorHost2::GetStartupFlags() { return m_dwStartupFlags; } -#endif //FEATURE_CORECLR #ifndef DACCESS_COMPILE -#if !defined(FEATURE_CORECLR) -/************************************************************************************* - ** ICLRPrivRuntime Methods - *************************************************************************************/ - -HRESULT CorHost2::GetInterface( - REFCLSID rclsid, - REFIID riid, - LPVOID * ppUnk) -{ - CONTRACTL { - NOTHROW; - GC_TRIGGERS; - MODE_PREEMPTIVE; - } CONTRACTL_END; - - HRESULT hr = S_OK; - - EX_TRY - { - if (rclsid == __uuidof(CLRPrivAppXBinder)) - { - CLRPrivBinderAppX * pBinder = CLRPrivBinderAppX::GetOrCreateBinder(); - hr = pBinder->QueryInterface(riid, ppUnk); - } - else - { - hr = E_NOINTERFACE; - } - } - EX_CATCH_HRESULT(hr); - - return hr; -} - -HRESULT CorHost2::CreateAppDomain( - LPCWSTR pwzFriendlyName, - ICLRPrivBinder * pBinder, - LPDWORD pdwAppDomainId) -{ - return _CreateAppDomain( - pwzFriendlyName, - 0 /* default security */, - nullptr, /* domain manager */ - nullptr, /* domain manager */ - 0, /* property count */ - nullptr, /* property names */ - nullptr, /* property values */ - pBinder, - pdwAppDomainId); -} - -HRESULT CorHost2::CreateDelegate( - DWORD appDomainID, - LPCWSTR wszAssemblyName, - LPCWSTR wszClassName, - LPCWSTR wszMethodName, - LPVOID * ppvDelegate) -{ - return _CreateDelegate(appDomainID, wszAssemblyName, wszClassName, - wszMethodName, reinterpret_cast<INT_PTR*>(ppvDelegate)); -} - -// Flag indicating if the EE was started up by an managed exe. Defined in ceemain.cpp. -extern BOOL g_fEEManagedEXEStartup; - -HRESULT CorHost2::ExecuteMain( - ICLRPrivBinder * pBinder, - int * pRetVal) -{ - STATIC_CONTRACT_GC_TRIGGERS; - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_ENTRY_POINT; - - HRESULT hr = S_OK; - - // If an exception passes through here, it will cause the - // "The application has generated an unhandled exception" dialog and offer to debug. - BEGIN_ENTRYPOINT_THROWS; - - // Indicates that the EE was started up by a managed exe. - g_fEEManagedEXEStartup = TRUE; - - IfFailGo(CorCommandLine::SetArgvW(WszGetCommandLine())); - - IfFailGo(EnsureEEStarted(COINITEE_MAIN)); - - INSTALL_UNWIND_AND_CONTINUE_HANDLER; - - // - // Look for the [STAThread] or [MTAThread] attribute - // TODO delete this code when we move to the default AppDomain - // - HMODULE hMod = WszGetModuleHandle(NULL); - - PEImageHolder pTempImage(PEImage::LoadImage(hMod)); - PEFileHolder pTempFile(PEFile::Open(pTempImage.Extract())); - - // Check for CustomAttributes - Set up the DefaultDomain and the main thread - // Note that this has to be done before ExplicitBind() as it - // affects the bind - mdToken tkEntryPoint = pTempFile->GetEntryPointToken(); - // <TODO>@TODO: What if the entrypoint is in another file of the assembly?</TODO> - ReleaseHolder<IMDInternalImport> scope(pTempFile->GetMDImportWithRef()); - // In theory, we should have a valid executable image and scope should never be NULL, but we've been - // getting Watson failures for AVs here due to ISVs modifying image headers and some new OS loader - // checks (see Dev10# 718530 and Windows 7# 615596) - if (scope == NULL) - { - ThrowHR(COR_E_BADIMAGEFORMAT); - } - - Thread::ApartmentState state = Thread::AS_Unknown; - - if((!IsNilToken(tkEntryPoint)) && (TypeFromToken(tkEntryPoint) == mdtMethodDef)) { - if (scope->IsValidToken(tkEntryPoint)) - state = SystemDomain::GetEntryPointThreadAptState(scope, tkEntryPoint); - else - ThrowHR(COR_E_BADIMAGEFORMAT); - } - - BOOL fSetGlobalSharePolicyUsingAttribute = FALSE; - - if((!IsNilToken(tkEntryPoint)) && (TypeFromToken(tkEntryPoint) == mdtMethodDef)) - { - // The global share policy needs to be set before initializing default domain - // so that it is in place for loading of appdomain manager. - fSetGlobalSharePolicyUsingAttribute = SystemDomain::SetGlobalSharePolicyUsingAttribute(scope, tkEntryPoint); - } - - // 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(scope, state); - - // This can potentially run managed code. - SystemDomain::InitializeDefaultDomain(FALSE, pBinder); - - // If we haven't set an explicit thread apartment state, set it after the - // AppDomainManager has got a chance to go set it in InitializeNewDomain. - if (state != Thread::AS_InSTA && state != Thread::AS_InMTA) - SystemDomain::SetThreadAptState(scope, state); - - if (fSetGlobalSharePolicyUsingAttribute) - SystemDomain::System()->DefaultDomain()->SetupLoaderOptimization(g_dwGlobalSharePolicy); - - ADID adId(DefaultADID); - - GCX_COOP(); - - ENTER_DOMAIN_ID(adId) - TESTHOOKCALL(EnteredAppDomain(adId.m_dwId)); - { - GCX_PREEMP(); - - AppDomain *pDomain = GetAppDomain(); - _ASSERTE(pDomain); - - PathString wzExeFileName; - - if (WszGetModuleFileName(nullptr, wzExeFileName) == 0) - IfFailThrow(E_UNEXPECTED); - - LPWSTR wzExeSimpleFileName = nullptr; - size_t cchExeSimpleFileName = 0; - SplitPathInterior( - wzExeFileName, - nullptr, nullptr, // drive - nullptr, nullptr, // dir - (LPCWSTR*)&wzExeSimpleFileName, &cchExeSimpleFileName, // filename - nullptr, nullptr); // ext - - // Remove the extension - wzExeSimpleFileName[cchExeSimpleFileName] = W('\0'); - - ReleaseHolder<IAssemblyName> pAssemblyName; - IfFailThrow(CreateAssemblyNameObject( - &pAssemblyName, // Returned IAssemblyName - wzExeSimpleFileName, // Name of assembly - CANOF_PARSE_DISPLAY_NAME, // Parse as display name - nullptr)); // Reserved - - AssemblySpec specExe; - specExe.InitializeSpec(pAssemblyName, nullptr, false); - - PEAssemblyHolder pPEAssembly = pDomain->BindAssemblySpec(&specExe, TRUE, FALSE); - - pDomain->SetRootAssembly(pDomain->LoadAssembly(NULL, pPEAssembly, FILE_ACTIVE)); - - LOG((LF_CLASSLOADER | LF_CORDB, - LL_INFO10, - "Created domain for an executable at %p\n", - (pDomain->GetRootAssembly()? pDomain->GetRootAssembly()->Parent() : NULL))); - TESTHOOKCALL(RuntimeStarted(RTS_CALLINGENTRYPOINT)); - - // Set the friendly name to indicate that this is an immersive domain. - pDomain->SetFriendlyName(W("Immersive Application Domain"), TRUE); - - // Execute the main method - // NOTE: we call the entry point with our entry point exception filter active - // after the AppDomain transition which is a bit different from classic apps. - // this is so that we have the correct context when notifying the debugger - // or invoking WER on the main thread and mimics the behavior of classic apps. - // the assumption is that AppX entry points are always invoked post-AD transition. - ExecuteMainInner(pDomain->GetRootAssembly()); - - // Get the global latched exit code instead of the return value from ExecuteMainMethod - // because in the case of a "void Main" method the return code is always 0, - // while the latched exit code is set in either case. - *pRetVal = GetLatchedExitCode(); - } - END_DOMAIN_TRANSITION; - TESTHOOKCALL(LeftAppDomain(adId.m_dwId)); - - UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; - -ErrExit: - END_ENTRYPOINT_THROWS; - - return hr; -} - -VOID CorHost2::ExecuteMainInner(Assembly* pRootAssembly) -{ - STATIC_CONTRACT_GC_TRIGGERS; - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_ENTRY_POINT; - - struct Param - { - Assembly* pRootAssembly; - } param; - - param.pRootAssembly = pRootAssembly; - - PAL_TRY(Param*, pParam, ¶m) - { - // since this is the thread 0 entry point for AppX apps we use - // the EntryPointFilter so that an unhandled exception here will - // trigger the same behavior as in classic apps. - pParam->pRootAssembly->ExecuteMainMethod(NULL, TRUE /* waitForOtherThreads */); - } - PAL_EXCEPT_FILTER(EntryPointFilter) - { - LOG((LF_STARTUP, LL_INFO10, "EntryPointFilter returned EXCEPTION_EXECUTE_HANDLER!")); - } - PAL_ENDTRY -} - -// static -HRESULT CorHost2::SetFlagsAndHostConfig(STARTUP_FLAGS dwStartupFlags, LPCWSTR pwzHostConfigFile, BOOL fFinalize) -{ - WRAPPER_NO_CONTRACT; - - HRESULT hr = E_INVALIDARG; - - if (pwzHostConfigFile == NULL) - pwzHostConfigFile = W(""); - - DangerousNonHostedSpinLockHolder lockHolder(&m_FlagsLock); - - if (m_dwFlagsFinalized) - { - // verify that flags and config file are the same - if (dwStartupFlags == m_dwStartupFlags && - _wcsicmp(pwzHostConfigFile, m_wzHostConfigFile) == 0) - { - hr = S_OK; - } - } - else - { - // overwrite the flags and config with the incoming values - if (wcslen(pwzHostConfigFile) < COUNTOF(m_wzHostConfigFile)) - { - VERIFY(wcscpy_s(m_wzHostConfigFile, COUNTOF(m_wzHostConfigFile), pwzHostConfigFile) == 0); - - // If they asked for the server gc but only have one processor, deny that option. - // Keep this in sync with shim logic in ComputeStartupFlagsAndFlavor that also switches to - // the workstation GC on uniprocessor boxes. - if (g_SystemInfo.dwNumberOfProcessors == 1 && (dwStartupFlags & STARTUP_SERVER_GC)) - dwStartupFlags = (STARTUP_FLAGS)(dwStartupFlags & ~(STARTUP_SERVER_GC | STARTUP_CONCURRENT_GC)); - - m_dwStartupFlags = dwStartupFlags; - - if (fFinalize) - m_dwFlagsFinalized = TRUE; - - hr = S_OK; - } - } - - return hr; -} - -// static -STARTUP_FLAGS CorHost2::GetStartupFlags() -{ - WRAPPER_NO_CONTRACT; - - if (!m_dwFlagsFinalized) // make sure we return consistent results - { - DangerousNonHostedSpinLockHolder lockHolder(&m_FlagsLock); - m_dwFlagsFinalized = TRUE; - } - - return m_dwStartupFlags; -} - -// static -LPCWSTR CorHost2::GetHostConfigFile() -{ - WRAPPER_NO_CONTRACT; - - if (!m_dwFlagsFinalized) // make sure we return consistent results - { - DangerousNonHostedSpinLockHolder lockHolder(&m_FlagsLock); - m_dwFlagsFinalized = TRUE; - } - - return m_wzHostConfigFile; -} - -// static -void CorHost2::GetDefaultAppDomainProperties(StringArrayList **pPropertyNames, StringArrayList **pPropertyValues) -{ - LIMITED_METHOD_CONTRACT; - - // We should only read these after the runtime has started to ensure that the host isn't modifying them - // still - _ASSERTE(g_fEEStarted || HasStarted()); - - *pPropertyNames = &s_defaultDomainPropertyNames; - *pPropertyValues = &s_defaultDomainPropertyValues; -} - -#endif // !FEATURE_CORECLR #ifdef FEATURE_COMINTEROP @@ -2644,370 +1198,12 @@ HRESULT GetCLRRuntimeHost(REFIID riid, IUnknown **ppUnk) return CorHost2::CreateObject(riid, (void**)ppUnk); } -#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR) - -HRESULT NextDomainWorker(AppDomainIterator *pEnum, - IUnknown** pAppDomain) -{ - CONTRACTL - { - DISABLED(NOTHROW); // nothrow contract's fs:0 handler gets called before the C++ EH fs:0 handler which is pushed in the prolog - GC_TRIGGERS; - SO_TOLERANT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - Thread *pThread = GetThread(); - BEGIN_SO_INTOLERANT_CODE_NOTHROW(pThread, return COR_E_STACKOVERFLOW); - - EX_TRY - { - GCX_COOP_THREAD_EXISTS(pThread); - - if (pEnum->Next()) - { - AppDomain* pDomain = pEnum->GetDomain(); - // Need to enter the AppDomain to synchronize access to the exposed - // object properly (can't just take the system domain mutex since we - // might need to run code that uses higher ranking crsts). - ENTER_DOMAIN_PTR(pDomain,ADV_ITERATOR) - { - - hr = pDomain->GetComIPForExposedObject(pAppDomain); - } - END_DOMAIN_TRANSITION; - } - else - { - hr = S_FALSE; - } - } - EX_CATCH_HRESULT(hr); - - END_SO_INTOLERANT_CODE; - - return hr; -} - -// Returns S_FALSE when there are no more domains. A domain -// is passed out only when S_OK is returned. -HRESULT CorRuntimeHostBase::NextDomain(HDOMAINENUM hEnum, - IUnknown** pAppDomain) -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - ENTRY_POINT; - } - CONTRACTL_END; - - if(hEnum == NULL || pAppDomain == NULL) - return E_POINTER; - - // If the runtime has not started, we have nothing to do. - if (!g_fEEStarted) - { - return HOST_E_CLRNOTAVAILABLE; - } - - HRESULT hr; - - BEGIN_ENTRYPOINT_NOTHROW; - - AppDomainIterator *pEnum = (AppDomainIterator *) hEnum; - - do - { - hr = NextDomainWorker(pEnum, pAppDomain); - // Might need to look at the next appdomain if we were attempting to get at - // the exposed appdomain object and were chucked out as the result of an - // appdomain unload. - } while (hr == COR_E_APPDOMAINUNLOADED); - END_ENTRYPOINT_NOTHROW; - return hr; -} - -// Creates a domain in the runtime. The identity array is -// a pointer to an array TYPE containing IIdentity objects defining -// the security identity. -HRESULT CorRuntimeHostBase::CreateDomainEx(LPCWSTR pwzFriendlyName, - IUnknown* pSetup, // Optional - IUnknown* pEvidence, // Optional - IUnknown ** pAppDomain) -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_PREEMPTIVE; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - if(!pwzFriendlyName) return E_POINTER; - if(pAppDomain == NULL) return E_POINTER; - if(!g_fEEStarted) return E_FAIL; - - BEGIN_ENTRYPOINT_NOTHROW; - - BEGIN_EXTERNAL_ENTRYPOINT(&hr); - { - GCX_COOP_THREAD_EXISTS(GET_THREAD()); - - struct _gc { - STRINGREF pName; - OBJECTREF pSetup; - OBJECTREF pEvidence; - APPDOMAINREF pDomain; - } gc; - ZeroMemory(&gc, sizeof(gc)); - - if (FAILED(hr = EnsureComStartedNoThrow())) - goto lDone; - - GCPROTECT_BEGIN(gc); - - gc.pName = StringObject::NewString(pwzFriendlyName); - - if(pSetup) - GetObjectRefFromComIP(&gc.pSetup, pSetup); - if(pEvidence) - GetObjectRefFromComIP(&gc.pEvidence, pEvidence); - - MethodDescCallSite createDomain(METHOD__APP_DOMAIN__CREATE_DOMAIN); - - ARG_SLOT args[3] = { - ObjToArgSlot(gc.pName), - ObjToArgSlot(gc.pEvidence), - ObjToArgSlot(gc.pSetup), - }; - - gc.pDomain = (APPDOMAINREF) createDomain.Call_RetOBJECTREF(args); - - *pAppDomain = GetComIPFromObjectRef((OBJECTREF*) &gc.pDomain); - - GCPROTECT_END(); - -lDone: ; - } - END_EXTERNAL_ENTRYPOINT; - - END_ENTRYPOINT_NOTHROW; - - return hr; -} - -// Close the enumeration releasing resources -HRESULT CorRuntimeHostBase::CloseEnum(HDOMAINENUM hEnum) -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - - BEGIN_ENTRYPOINT_NOTHROW; - - if(hEnum) { - AppDomainIterator* pEnum = (AppDomainIterator*) hEnum; - delete pEnum; - } - - END_ENTRYPOINT_NOTHROW; - return hr; -} - - -HRESULT CorRuntimeHostBase::CreateDomainSetup(IUnknown **pAppDomainSetup) -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - ENTRY_POINT; - MODE_PREEMPTIVE; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - - if (!pAppDomainSetup) - return E_POINTER; - - // If the runtime has not started, we have nothing to do. - if (!g_fEEStarted) - { - return HOST_E_CLRNOTAVAILABLE; - } - - // Create the domain. - BEGIN_ENTRYPOINT_NOTHROW; - - BEGIN_EXTERNAL_ENTRYPOINT(&hr); - { - GCX_COOP_THREAD_EXISTS(GET_THREAD()); - - struct _gc { - OBJECTREF pSetup; - } gc; - ZeroMemory(&gc, sizeof(gc)); - MethodTable* pMT = NULL; - - hr = EnsureComStartedNoThrow(); - if (FAILED(hr)) - goto lDone; - - pMT = MscorlibBinder::GetClass(CLASS__APPDOMAIN_SETUP); - - GCPROTECT_BEGIN(gc); - gc.pSetup = AllocateObject(pMT); - *pAppDomainSetup = GetComIPFromObjectRef((OBJECTREF*) &gc.pSetup); - GCPROTECT_END(); - -lDone: ; - } - END_EXTERNAL_ENTRYPOINT; - END_ENTRYPOINT_NOTHROW; - - return hr; -} - -HRESULT CorRuntimeHostBase::CreateEvidence(IUnknown **pEvidence) -{ - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - MODE_PREEMPTIVE; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - - if (!pEvidence) - return E_POINTER; - -#ifdef FEATURE_CAS_POLICY - - // If the runtime has not started, we have nothing to do. - if (!g_fEEStarted) - { - return HOST_E_CLRNOTAVAILABLE; - } - - // Create the domain. - BEGIN_ENTRYPOINT_NOTHROW; - - BEGIN_EXTERNAL_ENTRYPOINT(&hr); - { - GCX_COOP_THREAD_EXISTS(GET_THREAD()); - - struct _gc { - OBJECTREF pEvidence; - } gc; - ZeroMemory(&gc, sizeof(gc)); - - MethodTable* pMT = NULL; - - hr = EnsureComStartedNoThrow(); - if (FAILED(hr)) - goto lDone; - - pMT = MscorlibBinder::GetClass(CLASS__EVIDENCE); - - GCPROTECT_BEGIN(gc); - gc.pEvidence = AllocateObject(pMT); - MethodDescCallSite ctor(METHOD__EVIDENCE__CTOR, &(gc.pEvidence)); - - // Call the Evidence class constructor. - ARG_SLOT CtorArgs[] = - { - ObjToArgSlot(gc.pEvidence) - }; - ctor.Call(CtorArgs); - - *pEvidence = GetComIPFromObjectRef((OBJECTREF*) &gc.pEvidence); - GCPROTECT_END(); - -lDone: ; - } - END_EXTERNAL_ENTRYPOINT; - END_ENTRYPOINT_NOTHROW; -#else // !FEATURE_CAS_POLICY - // There is no Evidence class support without CAS policy. - return E_NOTIMPL; -#endif // FEATURE_CAS_POLICY - - return hr; -} - -HRESULT CorRuntimeHostBase::UnloadDomain(IUnknown *pUnkDomain) -{ - CONTRACTL - { - DISABLED(NOTHROW); - GC_TRIGGERS; - MODE_ANY; - FORBID_FAULT; - ENTRY_POINT; - } - CONTRACTL_END; - - if (!pUnkDomain) - return E_POINTER; - - // If the runtime has not started, we have nothing to do. - if (!g_fEEStarted) - { - return HOST_E_CLRNOTAVAILABLE; - } - - CONTRACT_VIOLATION(FaultViolation); // This entire function is full of OOM potential: must fix. - - HRESULT hr = S_OK; - DWORD dwDomainId = 0; - BEGIN_ENTRYPOINT_NOTHROW; - - _ASSERTE (g_fComStarted); - - { - SystemDomain::LockHolder lh; - - ComCallWrapper* pWrap = GetCCWFromIUnknown(pUnkDomain, FALSE); - if (!pWrap) - { - hr = COR_E_APPDOMAINUNLOADED; - } - if (SUCCEEDED(hr)) - { - dwDomainId = pWrap->GetDomainID().m_dwId; - } - } - if (SUCCEEDED(hr)) - { - hr = UnloadAppDomain(dwDomainId, TRUE); - } - END_ENTRYPOINT_NOTHROW; - - return hr; -} - -#endif // FEATURE_COMINTEROP && !FEATURE_CORECLR STDMETHODIMP CorHost2::UnloadAppDomain(DWORD dwDomainId, BOOL fWaitUntilDone) { WRAPPER_NO_CONTRACT; STATIC_CONTRACT_SO_TOLERANT; -#ifdef FEATURE_CORECLR if (!m_fStarted) return HOST_E_INVALIDOPERATION; @@ -3056,7 +1252,6 @@ STDMETHODIMP CorHost2::UnloadAppDomain(DWORD dwDomainId, BOOL fWaitUntilDone) return hr; } else -#endif // FEATURE_CORECLR return CorRuntimeHostBase::UnloadAppDomain(dwDomainId, fWaitUntilDone); } @@ -3093,9 +1288,7 @@ HRESULT CorRuntimeHostBase::UnloadAppDomain(DWORD dwDomainId, BOOL fSync) // for this scope only. CONTRACT_VIOLATION(FaultViolation); if (!IsRuntimeActive() - #ifdef FEATURE_CORECLR || !m_fStarted - #endif // FEATURE_CORECLR ) { return HOST_E_CLRNOTAVAILABLE; @@ -3117,126 +1310,6 @@ HRESULT CorRuntimeHostBase::UnloadAppDomain(DWORD dwDomainId, BOOL fSync) //***************************************************************************** // Fiber Methods //***************************************************************************** -#if !defined(FEATURE_CORECLR) // simple hosting -HRESULT CorHost::CreateLogicalThreadState() -{ - CONTRACTL - { - NOTHROW; - DISABLED(GC_TRIGGERS); - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - - BEGIN_ENTRYPOINT_NOTHROW; - if (CorHost::GetHostVersion() != 1) - { - hr=HOST_E_INVALIDOPERATION; - } - else - { - _ASSERTE (GetThread() == 0 || GetThread()->HasRightCacheStackBase()); - /* Thread *thread = */ SetupThreadNoThrow(&hr); - - } - END_ENTRYPOINT_NOTHROW; - return hr; -} - - -HRESULT CorHost::DeleteLogicalThreadState() -{ - if (CorHost::GetHostVersion() != 1) - { - return HOST_E_INVALIDOPERATION; - } - - Thread *pThread = GetThread(); - if (!pThread) - return E_UNEXPECTED; - - CONTRACTL - { - NOTHROW; - GC_TRIGGERS; - ENTRY_POINT; - } - CONTRACTL_END; - HRESULT hr = S_OK; - BEGIN_ENTRYPOINT_NOTHROW; - // We need to reset the TrapReturningThread count that was - // set when a thread is requested to be aborted. Otherwise - // every stub call is going to go through a slow path. - if (pThread->IsAbortRequested()) - pThread->UnmarkThreadForAbort(Thread::TAR_ALL); - - // see code:Thread::OnThreadTerminate#ReportDeadOnThreadTerminate - pThread->SetThreadState(Thread::TS_ReportDead); - - pThread->OnThreadTerminate(FALSE); - END_ENTRYPOINT_NOTHROW; - return hr; -} - - -HRESULT CorHost::SwitchInLogicalThreadState(DWORD *pFiberCookie) -{ - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_MODE_ANY; - STATIC_CONTRACT_ENTRY_POINT; - - if (CorHost::GetHostVersion() != 1) - { - return HOST_E_INVALIDOPERATION; - } - - if (!pFiberCookie) - { - return E_POINTER; - } - - HRESULT hr = S_OK; - BEGIN_ENTRYPOINT_NOTHROW; - - hr = ((Thread*)pFiberCookie)->SwitchIn(::GetCurrentThread()); - - END_ENTRYPOINT_NOTHROW; - return hr; - -} - -HRESULT CorHost::SwitchOutLogicalThreadState(DWORD **pFiberCookie) -{ - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_MODE_ANY; - STATIC_CONTRACT_ENTRY_POINT; - - if (CorHost::GetHostVersion() != 1) - { - return HOST_E_INVALIDOPERATION; - } - - if (!pFiberCookie) - { - return E_POINTER; - } - - Thread *pThread = GetThread(); - if (!pThread) - { - return E_UNEXPECTED; - } - - pThread->InternalSwitchOut(); - *pFiberCookie = (DWORD*)pThread; - - return S_OK; -} -#endif // !defined(FEATURE_CORECLR) HRESULT CorRuntimeHostBase::LocksHeldByLogicalThread(DWORD *pCount) { @@ -3267,242 +1340,6 @@ HRESULT CorRuntimeHostBase::LocksHeldByLogicalThread(DWORD *pCount) //***************************************************************************** // ICorConfiguration //***************************************************************************** -#if !defined(FEATURE_CORECLR) -IGCThreadControl *CorConfiguration::m_CachedGCThreadControl = 0; -IGCHostControl *CorConfiguration::m_CachedGCHostControl = 0; -IDebuggerThreadControl *CorConfiguration::m_CachedDebuggerThreadControl = 0; -DWORD *CorConfiguration::m_DSTArray = 0; -DWORD CorConfiguration::m_DSTCount = 0; -DWORD CorConfiguration::m_DSTArraySize = 0; - -// *** ICorConfiguration methods *** - - -HRESULT CorConfiguration::SetGCThreadControl(IGCThreadControl *pGCThreadControl) -{ - if (!pGCThreadControl) - return E_POINTER; - - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - ENTRY_POINT; - } - CONTRACTL_END; - - BEGIN_ENTRYPOINT_NOTHROW; - - if (m_CachedGCThreadControl) - m_CachedGCThreadControl->Release(); - - m_CachedGCThreadControl = pGCThreadControl; - - if (m_CachedGCThreadControl) - m_CachedGCThreadControl->AddRef(); - - END_ENTRYPOINT_NOTHROW; - - return S_OK; -} - -HRESULT CorConfiguration::SetGCHostControl(IGCHostControl *pGCHostControl) -{ - if (!pGCHostControl) - return E_POINTER; - - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - ENTRY_POINT; - } - CONTRACTL_END; - - BEGIN_ENTRYPOINT_NOTHROW; - - if (m_CachedGCHostControl) - m_CachedGCHostControl->Release(); - - m_CachedGCHostControl = pGCHostControl; - - if (m_CachedGCHostControl) - m_CachedGCHostControl->AddRef(); - - END_ENTRYPOINT_NOTHROW; - - return S_OK; -} - -HRESULT CorConfiguration::SetDebuggerThreadControl(IDebuggerThreadControl *pDebuggerThreadControl) -{ - if (!pDebuggerThreadControl) - return E_POINTER; - - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - BEGIN_ENTRYPOINT_NOTHROW; - -#ifdef DEBUGGING_SUPPORTED - // Can't change the debugger thread control object once its been set. - if (m_CachedDebuggerThreadControl != NULL) - IfFailGo(E_INVALIDARG); - - m_CachedDebuggerThreadControl = pDebuggerThreadControl; - - // If debugging is already initialized then provide this interface pointer to it. - // It will also addref the new one and release the old one. - if (g_pDebugInterface) - g_pDebugInterface->SetIDbgThreadControl(pDebuggerThreadControl); - - if (m_CachedDebuggerThreadControl) - m_CachedDebuggerThreadControl->AddRef(); - - hr = S_OK; -#else // !DEBUGGING_SUPPORTED - hr = E_NOTIMPL; -#endif // !DEBUGGING_SUPPORTED - -ErrExit: - END_ENTRYPOINT_NOTHROW; - return hr; - -} - - -HRESULT CorConfiguration::AddDebuggerSpecialThread(DWORD dwSpecialThreadId) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - ENTRY_POINT; // debugging not hardened for SO - } - CONTRACTL_END; - - HRESULT hr = S_OK; - BEGIN_ENTRYPOINT_NOTHROW; - - -#ifdef DEBUGGING_SUPPORTED - // If it's already in the list, don't add it again. - if (IsDebuggerSpecialThread(dwSpecialThreadId)) - { - hr = S_OK; - goto ErrExit; - } - // Grow the array if necessary. - if (m_DSTCount >= m_DSTArraySize) - { - // There's probably only ever gonna be one or two of these - // things, so we'll start small. - DWORD newSize = (m_DSTArraySize == 0) ? 2 : m_DSTArraySize * 2; - - DWORD *newArray = new (nothrow) DWORD[newSize]; - IfNullGo(newArray); - - // If we're growing instead of starting, then copy the old array. - if (m_DSTArray) - { - memcpy(newArray, m_DSTArray, m_DSTArraySize * sizeof(DWORD)); - delete [] m_DSTArray; - } - - // Update to the new array and size. - m_DSTArray = newArray; - m_DSTArraySize = newSize; - } - - // Save the new thread ID. - m_DSTArray[m_DSTCount++] = dwSpecialThreadId; - - hr = (RefreshDebuggerSpecialThreadList()); -#else // !DEBUGGING_SUPPORTED - hr = E_NOTIMPL; -#endif // !DEBUGGING_SUPPORTED -ErrExit: - END_ENTRYPOINT_NOTHROW; - return hr; - -} -// Helper function to update the thread list in the debugger control block -HRESULT CorConfiguration::RefreshDebuggerSpecialThreadList() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - -#ifdef DEBUGGING_SUPPORTED - HRESULT hr = S_OK; - - if (g_pDebugInterface) - { - // Inform the debugger services that this list has changed - hr = g_pDebugInterface->UpdateSpecialThreadList( - m_DSTCount, m_DSTArray); - - _ASSERTE(SUCCEEDED(hr)); - } - - return (hr); -#else // !DEBUGGING_SUPPORTED - return E_NOTIMPL; -#endif // !DEBUGGING_SUPPORTED -} - - -// Helper func that returns true if the thread is in the debugger special thread list -BOOL CorConfiguration::IsDebuggerSpecialThread(DWORD dwThreadId) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - for (DWORD i = 0; i < m_DSTCount; i++) - { - if (m_DSTArray[i] == dwThreadId) - return (TRUE); - } - - return (FALSE); -} - - -// Clean up any debugger thread control object we may be holding, called at shutdown. -void CorConfiguration::CleanupDebuggerThreadControl() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - if (m_CachedDebuggerThreadControl != NULL) - { - // Note: we don't release the IDebuggerThreadControl object if we're cleaning up from - // our DllMain. The DLL that implements the object may already have been unloaded. - // Leaking the object is okay... the PDM doesn't care. - if (!IsAtProcessExit()) - m_CachedDebuggerThreadControl->Release(); - - m_CachedDebuggerThreadControl = NULL; - } -} -#endif // !defined(FEATURE_CORECLR) //***************************************************************************** // IUnknown @@ -3520,20 +1357,6 @@ ULONG CorRuntimeHostBase::AddRef() return InterlockedIncrement(&m_cRef); } -#if !defined(FEATURE_CORECLR) // simple hosting -ULONG CorHost::Release() -{ - LIMITED_METHOD_CONTRACT; - STATIC_CONTRACT_SO_TOLERANT; - - ULONG cRef = InterlockedDecrement(&m_cRef); - if (!cRef) { - delete this; - } - - return (cRef); -} -#endif // !defined(FEATURE_CORECLR) ULONG CorHost2::Release() { @@ -3541,72 +1364,12 @@ ULONG CorHost2::Release() ULONG cRef = InterlockedDecrement(&m_cRef); if (!cRef) { -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - // CorHost2 is allocated before host memory interface is set up. - if (GetHostMemoryManager() == NULL) -#endif // FEATURE_INCLUDE_ALL_INTERFACES delete this; } return (cRef); } -#if !defined(FEATURE_CORECLR) // simple hosting -HRESULT CorHost::QueryInterface(REFIID riid, void **ppUnk) -{ - if (!ppUnk) - return E_POINTER; - - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - SO_TOLERANT; // no global state updates that need guarding. - } - CONTRACTL_END; - - if (ppUnk == NULL) - { - return E_POINTER; - } - - *ppUnk = 0; - - // Deliberately do NOT hand out ICorConfiguration. They must explicitly call - // GetConfiguration to obtain that interface. - if (riid == IID_IUnknown) - *ppUnk = (IUnknown *) (ICorRuntimeHost *) this; - else if (riid == IID_ICorRuntimeHost) - { - ULONG version = 1; - if (m_Version == 0) - FastInterlockCompareExchange((LONG*)&m_Version, version, 0); - - if (m_Version != version && (g_singleVersionHosting || !g_fEEStarted)) - { - return HOST_E_INVALIDOPERATION; - } - - *ppUnk = (ICorRuntimeHost *) this; - } - else if (riid == IID_ICorThreadpool) - *ppUnk = (ICorThreadpool *) this; - else if (riid == IID_IGCHost) - *ppUnk = (IGCHost *) this; - else if (riid == IID_IGCHost2) - *ppUnk = (IGCHost2 *) this; - else if (riid == IID_IValidator) - *ppUnk = (IValidator *) this; - else if (riid == IID_IDebuggerInfo) - *ppUnk = (IDebuggerInfo *) this; - else if (riid == IID_ICLRExecutionManager) - *ppUnk = (ICLRExecutionManager *) this; - else - return (E_NOINTERFACE); - AddRef(); - return (S_OK); -} -#endif // !defined(FEATURE_CORECLR) HRESULT CorHost2::QueryInterface(REFIID riid, void **ppUnk) @@ -3633,7 +1396,6 @@ HRESULT CorHost2::QueryInterface(REFIID riid, void **ppUnk) // GetConfiguration to obtain that interface. if (riid == IID_IUnknown) *ppUnk = static_cast<IUnknown *>(static_cast<ICLRRuntimeHost *>(this)); -#ifdef FEATURE_CORECLR // CoreCLR only supports IID_ICLRRuntimeHost2 else if (riid == IID_ICLRRuntimeHost2) { ULONG version = 2; @@ -3642,16 +1404,6 @@ HRESULT CorHost2::QueryInterface(REFIID riid, void **ppUnk) *ppUnk = static_cast<ICLRRuntimeHost2 *>(this); } -#else // DesktopCLR only supports IID_ICLRRuntimeHost - else if (riid == IID_ICLRRuntimeHost) - { - ULONG version = 2; - if (m_Version == 0) - FastInterlockCompareExchange((LONG*)&m_Version, version, 0); - - *ppUnk = static_cast<ICLRRuntimeHost *>(this); - } -#endif // FEATURE_CORECLR else if (riid == IID_ICLRExecutionManager) { ULONG version = 2; @@ -3660,79 +1412,18 @@ HRESULT CorHost2::QueryInterface(REFIID riid, void **ppUnk) *ppUnk = static_cast<ICLRExecutionManager *>(this); } -#if !defined(FEATURE_CORECLR) - else if (riid == __uuidof(ICLRPrivRuntime)) - { - ULONG version = 2; - if (m_Version == 0) - FastInterlockCompareExchange((LONG*)&m_Version, version, 0); - - *ppUnk = static_cast<ICLRPrivRuntime *>(this); - } -#endif #ifndef FEATURE_PAL else if (riid == IID_IPrivateManagedExceptionReporting) { *ppUnk = static_cast<IPrivateManagedExceptionReporting *>(this); } #endif // !FEATURE_PAL -#ifndef FEATURE_CORECLR - else if (riid == IID_ICorThreadpool) - *ppUnk = static_cast<ICorThreadpool *>(this); - // TODO: wwl Remove this after SQL uses new interface. - else if (riid == IID_IGCHost && - GetHostVersion() == 3) - *ppUnk = static_cast<IGCHost *>(this); - else if (riid == IID_ICLRValidator) - *ppUnk = static_cast<ICLRValidator *>(this); - else if (riid == IID_IDebuggerInfo) - *ppUnk = static_cast<IDebuggerInfo *>(this); -#ifdef FEATURE_TESTHOOKS - else if (riid == IID_ICLRTestHookManager) - { - *ppUnk=CLRTestHookManager::Start(); - if(*ppUnk==NULL) - return E_OUTOFMEMORY; - } -#endif // FEATURE_TESTHOOKS -#endif // FEATURE_CORECLR else return (E_NOINTERFACE); AddRef(); return (S_OK); } -#ifndef FEATURE_CORECLR // CorHost isn't exposed externally -//***************************************************************************** -// Called by the class factory template to create a new instance of this object. -//***************************************************************************** -HRESULT CorHost::CreateObject(REFIID riid, void **ppUnk) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - SO_TOLERANT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - - CorHost *pCorHost = new (nothrow) CorHost(); - if (!pCorHost) - { - hr = E_OUTOFMEMORY; - } - else - { - hr = pCorHost->QueryInterface(riid, ppUnk); - - if (FAILED(hr)) - delete pCorHost; - } - return (hr); -} -#endif // FEATURE_CORECLR #ifndef FEATURE_PAL HRESULT CorHost2::GetBucketParametersForCurrentException(BucketParameters *pParams) @@ -3849,34 +1540,6 @@ HRESULT CorRuntimeHostBase::MapFile(HANDLE hFile, HMODULE* phHandle) /////////////////////////////////////////////////////////////////////////////// // IDebuggerInfo::IsDebuggerAttached -#if !defined(FEATURE_CORECLR) -HRESULT CorDebuggerInfo::IsDebuggerAttached(BOOL *pbAttached) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - BEGIN_ENTRYPOINT_NOTHROW; - - if (pbAttached == NULL) - hr = E_INVALIDARG; - else -#ifdef DEBUGGING_SUPPORTED - *pbAttached = (CORDebuggerAttached() != 0); -#else - *pbAttached = FALSE; -#endif - - END_ENTRYPOINT_NOTHROW; - - return hr; -} -#endif // !defined(FEATURE_CORECLR) LONG CorHost2::m_RefCount = 0; @@ -3886,440 +1549,6 @@ LPCWSTR CorHost2::s_wszAppDomainManagerAsm = NULL; LPCWSTR CorHost2::s_wszAppDomainManagerType = NULL; EInitializeNewDomainFlags CorHost2::s_dwDomainManagerInitFlags = eInitializeNewDomainFlags_None; -#ifndef FEATURE_CORECLR // not supported - -StringArrayList CorHost2::s_defaultDomainPropertyNames; -StringArrayList CorHost2::s_defaultDomainPropertyValues; - -IHostMemoryManager *CorHost2::m_HostMemoryManager = NULL; -IHostMalloc *CorHost2::m_HostMalloc = NULL; -IHostTaskManager *CorHost2::m_HostTaskManager = NULL; -IHostThreadpoolManager *CorHost2::m_HostThreadpoolManager = NULL; -IHostIoCompletionManager *CorHost2::m_HostIoCompletionManager = NULL; -IHostSyncManager *CorHost2::m_HostSyncManager = NULL; -IHostAssemblyManager *CorHost2::m_HostAssemblyManager = NULL; -IHostGCManager *CorHost2::m_HostGCManager = NULL; -IHostSecurityManager *CorHost2::m_HostSecurityManager = NULL; -IHostPolicyManager *CorHost2::m_HostPolicyManager = NULL; -int CorHost2::m_HostOverlappedExtensionSize = -1; - -STARTUP_FLAGS CorHost2::m_dwStartupFlags = STARTUP_CONCURRENT_GC; -WCHAR CorHost2::m_wzHostConfigFile[_MAX_PATH] = { 0 }; - -BOOL CorHost2::m_dwFlagsFinalized = FALSE; -DangerousNonHostedSpinLock CorHost2::m_FlagsLock; - -class CCLRMemoryNotificationCallback: public ICLRMemoryNotificationCallback -{ -public: - virtual HRESULT STDMETHODCALLTYPE OnMemoryNotification(EMemoryAvailable eMemoryAvailable) { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - ENTRY_POINT; - } - CONTRACTL_END; - - // We have not started runtime yet. - if (!g_fEEStarted) - return S_OK; - - BEGIN_ENTRYPOINT_NOTHROW; - - switch (eMemoryAvailable) - { - case eMemoryAvailableLow: - STRESS_LOG0(LF_GC, LL_INFO100, "Host delivers memory notification: Low\n"); - break; - case eMemoryAvailableNeutral: - STRESS_LOG0(LF_GC, LL_INFO100, "Host delivers memory notification: Neutral\n"); - break; - case eMemoryAvailableHigh: - STRESS_LOG0(LF_GC, LL_INFO100, "Host delivers memory notification: High\n"); - break; - } - static DWORD lastTime = (DWORD)-1; - if (eMemoryAvailable == eMemoryAvailableLow) - { - FastInterlockIncrement ((LONG *)&g_bLowMemoryFromHost); - DWORD curTime = GetTickCount(); - if (curTime < lastTime || curTime - lastTime >= 0x2000) - { - lastTime = curTime; - FinalizerThread::EnableFinalization(); - } - } - else - { - FastInterlockExchange ((LONG *)&g_bLowMemoryFromHost, FALSE); - } - END_ENTRYPOINT_NOTHROW; - - return S_OK; - } - - virtual ULONG STDMETHODCALLTYPE AddRef(void) - { - LIMITED_METHOD_CONTRACT; - return 1; - } - - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) - { - LIMITED_METHOD_CONTRACT; - if (riid != IID_ICLRMemoryNotificationCallback && riid != IID_IUnknown) - return (E_NOINTERFACE); - *ppvObject = this; - return S_OK; - } - - virtual ULONG STDMETHODCALLTYPE Release(void) - { - LIMITED_METHOD_CONTRACT; - return 1; - } -}; - -static CCLRMemoryNotificationCallback s_MemoryNotification; - -class CLRTaskManager : public ICLRTaskManager -{ -public: - virtual ULONG STDMETHODCALLTYPE AddRef(void) - { - LIMITED_METHOD_CONTRACT; - return 1; - } - - virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { - LIMITED_METHOD_CONTRACT; - if (riid != IID_ICLRTaskManager && riid != IID_IUnknown) - return (E_NOINTERFACE); - *ppvObject = this; - return S_OK; - } - - virtual ULONG STDMETHODCALLTYPE Release(void) - { - LIMITED_METHOD_CONTRACT; - return 1; - } - - virtual HRESULT STDMETHODCALLTYPE CreateTask(ICLRTask **pTask) - { - CONTRACTL - { - NOTHROW; - DISABLED(GC_NOTRIGGER); - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - BEGIN_ENTRYPOINT_NOTHROW; - -#ifdef _DEBUG - _ASSERTE (!CLRTaskHosted() || GetCurrentHostTask()); -#endif - _ASSERTE (GetThread() == NULL); - Thread *pThread = NULL; - pThread = SetupThreadNoThrow(&hr); - *pTask = pThread; - - END_ENTRYPOINT_NOTHROW; - - return hr; - } - - virtual HRESULT STDMETHODCALLTYPE GetCurrentTask(ICLRTask **pTask) - { - // This function may be called due SQL SwitchIn/Out. Contract may - // force memory allocation which is not allowed during Switch. - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_SO_TOLERANT; - STATIC_CONTRACT_ENTRY_POINT; - - *pTask = GetThread(); - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE SetUILocale(LCID lcid) - { - Thread *pThread = GetThread(); - if (pThread == NULL) - return HOST_E_INVALIDOPERATION; - - CONTRACTL - { - GC_TRIGGERS; - NOTHROW; - MODE_PREEMPTIVE; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - //BEGIN_ENTRYPOINT_NOTHROW; - BEGIN_EXTERNAL_ENTRYPOINT(&hr) - { - pThread->SetCultureId(lcid,TRUE); - } - END_EXTERNAL_ENTRYPOINT; - //END_ENTRYPOINT_NOTHROW; - - return hr; - } - - virtual HRESULT STDMETHODCALLTYPE SetLocale(LCID lcid) - { - Thread *pThread = GetThread(); - if (pThread == NULL) - return HOST_E_INVALIDOPERATION; - - CONTRACTL - { - GC_TRIGGERS; - NOTHROW; - MODE_PREEMPTIVE; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - //BEGIN_ENTRYPOINT_NOTHROW; - - BEGIN_EXTERNAL_ENTRYPOINT(&hr) - { - pThread->SetCultureId(lcid,FALSE); - } - END_EXTERNAL_ENTRYPOINT; - //END_ENTRYPOINT_NOTHROW; - return hr; - } - - virtual HRESULT STDMETHODCALLTYPE GetCurrentTaskType(ETaskType *pTaskType) - { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - ENTRY_POINT; - } - CONTRACTL_END; - - BEGIN_ENTRYPOINT_NOTHROW; - *pTaskType = ::GetCurrentTaskType(); - END_ENTRYPOINT_NOTHROW; - - return S_OK; - } -}; - -static CLRTaskManager s_CLRTaskManager; - -class CLRSyncManager : public ICLRSyncManager -{ -public: - virtual HRESULT STDMETHODCALLTYPE GetMonitorOwner(SIZE_T Cookie, - IHostTask **ppOwnerHostTask) - { - CONTRACTL - { - NOTHROW; - MODE_PREEMPTIVE; - GC_NOTRIGGER; - ENTRY_POINT;; - } - CONTRACTL_END; - - BEGIN_ENTRYPOINT_NOTHROW; - - // Cookie is the SyncBlock - // <TODO>TODO: Lifetime of Cookie?</TODO> - AwareLock* pAwareLock = (AwareLock*)Cookie; - IHostTask *pTask = NULL; - Thread *pThread = pAwareLock->GetOwningThread(); - if (pThread) - { - ThreadStoreLockHolder tsLock; - pThread = pAwareLock->GetOwningThread(); - if (pThread) - { - // See if the lock is orphaned, and the Thread object has been deleted - Thread *pWalk = NULL; - while ((pWalk = ThreadStore::GetAllThreadList(pWalk, 0, 0)) != NULL) - { - if (pWalk == pThread) - { - pTask = pThread->GetHostTaskWithAddRef(); - break; - } - } - } - } - - *ppOwnerHostTask = pTask; - - END_ENTRYPOINT_NOTHROW; - - - return S_OK; - } - virtual HRESULT STDMETHODCALLTYPE CreateRWLockOwnerIterator(SIZE_T Cookie, - SIZE_T *pIterator) { - Thread *pThread = GetThread(); - - // We may open a window for GC here. - // A host should not hijack a coop thread to do deadlock detection. - if (pThread && pThread->PreemptiveGCDisabled()) - return HOST_E_INVALIDOPERATION; - - CONTRACTL - { - NOTHROW; - MODE_PREEMPTIVE; - GC_NOTRIGGER; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = E_FAIL; - -#ifdef FEATURE_RWLOCK - BEGIN_ENTRYPOINT_NOTHROW; - ThreadStoreLockHolder tsLock; - // Cookie is a weak handle. We need to make sure that the object is not moving. - CRWLock *pRWLock = *(CRWLock **) Cookie; - *pIterator = NULL; - if (pRWLock == NULL) - { - hr = S_OK; - } - else - { - hr = pRWLock->CreateOwnerIterator(pIterator); - } - END_ENTRYPOINT_NOTHROW; -#endif // FEATURE_RWLOCK - - return hr; - } - - virtual HRESULT STDMETHODCALLTYPE GetRWLockOwnerNext(SIZE_T Iterator, - IHostTask **ppOwnerHostTask) - { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - ENTRY_POINT; - } - CONTRACTL_END; - -#ifdef FEATURE_RWLOCK - BEGIN_ENTRYPOINT_NOTHROW; - CRWLock::GetNextOwner(Iterator,ppOwnerHostTask); - END_ENTRYPOINT_NOTHROW; -#endif // FEATURE_RWLOCK - - return S_OK; - } - - virtual HRESULT STDMETHODCALLTYPE DeleteRWLockOwnerIterator(SIZE_T Iterator) - { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - ENTRY_POINT; - } - CONTRACTL_END; - -#ifdef FEATURE_RWLOCK - BEGIN_ENTRYPOINT_NOTHROW; - CRWLock::DeleteOwnerIterator(Iterator); - END_ENTRYPOINT_NOTHROW; -#endif // FEATURE_RWLOCK - - return S_OK; - } - - virtual ULONG STDMETHODCALLTYPE AddRef(void) - { - LIMITED_METHOD_CONTRACT; - return 1; - } - - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) - { - LIMITED_METHOD_CONTRACT; - if (riid != IID_ICLRSyncManager && riid != IID_IUnknown) - return (E_NOINTERFACE); - *ppvObject = this; - return S_OK; - } - - virtual ULONG STDMETHODCALLTYPE Release(void) - { - LIMITED_METHOD_CONTRACT; - return 1; - } -}; - -static CLRSyncManager s_CLRSyncManager; - -extern void HostIOCompletionCallback(DWORD ErrorCode, - DWORD numBytesTransferred, - LPOVERLAPPED lpOverlapped); -class CCLRIoCompletionManager :public ICLRIoCompletionManager -{ -public: - virtual HRESULT STDMETHODCALLTYPE OnComplete(DWORD dwErrorCode, - DWORD NumberOfBytesTransferred, - void* pvOverlapped) - { - WRAPPER_NO_CONTRACT; - STATIC_CONTRACT_ENTRY_POINT; - - if (pvOverlapped) - { - BEGIN_ENTRYPOINT_NOTHROW; - HostIOCompletionCallback (dwErrorCode, NumberOfBytesTransferred, (LPOVERLAPPED)pvOverlapped); - END_ENTRYPOINT_NOTHROW; - } - - return S_OK; - } - - virtual ULONG STDMETHODCALLTYPE AddRef(void) - { - STATIC_CONTRACT_SO_TOLERANT; - LIMITED_METHOD_CONTRACT; - return 1; - } - - virtual ULONG STDMETHODCALLTYPE Release(void) - { - STATIC_CONTRACT_SO_TOLERANT; - LIMITED_METHOD_CONTRACT; - return 1; - } - BEGIN_INTERFACE HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) - { - STATIC_CONTRACT_SO_TOLERANT; - LIMITED_METHOD_CONTRACT; - if (riid != IID_ICLRIoCompletionManager && riid != IID_IUnknown) - return (E_NOINTERFACE); - *ppvObject = this; - return S_OK; - } -}; - -static CCLRIoCompletionManager s_CLRIoCompletionManager; -#endif // FEATURE_CORECLR #ifdef _DEBUG extern void ValidateHostInterface(); @@ -4327,19 +1556,11 @@ extern void ValidateHostInterface(); // fusion's global copy of host assembly manager stuff BOOL g_bFusionHosted = FALSE; -#ifdef FEATURE_INCLUDE_ALL_INTERFACES -ICLRAssemblyReferenceList *g_pHostAsmList = NULL; -IHostAssemblyStore *g_pHostAssemblyStore = NULL; -#endif // FEATURE_INCLUDE_ALL_INTERFACES /*static*/ BOOL CorHost2::IsLoadFromBlocked() // LoadFrom, LoadFile and Load(byte[]) are blocked in certain hosting scenarios { LIMITED_METHOD_CONTRACT; -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - return (g_bFusionHosted && (g_pHostAsmList != NULL)); -#else // !FEATURE_INCLUDE_ALL_INTERFACES return FALSE; // as g_pHostAsmList is not defined for CoreCLR; hence above expression will be FALSE. -#endif // FEATURE_INCLUDE_ALL_INTERFACES } static Volatile<BOOL> fOneOnly = 0; @@ -4375,181 +1596,9 @@ HRESULT CorHost2::SetHostControl(IHostControl* pHostControl) while (FastInterlockExchange((LONG*)&fOneOnly, 1) == 1) { - #ifndef FEATURE_CORECLR - if (m_HostTaskManager != NULL) - { - m_HostTaskManager->SwitchToTask(0); - } - else - { - IHostTaskManager *pHostTaskManager = NULL; - if (pHostControl->GetHostManager(IID_IHostTaskManager, (void**)&pHostTaskManager) == S_OK && - pHostTaskManager != NULL) - { - pHostTaskManager->SwitchToTask(0); - pHostTaskManager->Release(); - } - else - { - __SwitchToThread(0, ++dwSwitchCount); - } - } - #else __SwitchToThread(0, ++dwSwitchCount); - #endif // FEATURE_CORECLR } -#ifndef FEATURE_CORECLR - -#ifdef _DEBUG - ValidateHostInterface(); -#endif - -#ifdef _DEBUG - DWORD dbg_HostManagerConfig = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_HostManagerConfig); -#endif - - IHostMemoryManager *memoryManager = NULL; - IHostTaskManager *taskManager = NULL; - IHostThreadpoolManager *threadpoolManager = NULL; - IHostIoCompletionManager *ioCompletionManager = NULL; - IHostSyncManager *syncManager = NULL; - IHostAssemblyManager *assemblyManager = NULL; - IHostGCManager *gcManager = NULL; - IHostSecurityManager *securityManager = NULL; - IHostPolicyManager *policyManager = NULL; - - if (m_HostMemoryManager == NULL && -#ifdef _DEBUG - (dbg_HostManagerConfig & CLRMEMORYHOSTED) && -#endif - pHostControl->GetHostManager(IID_IHostMemoryManager,(void**)&memoryManager) == S_OK && - memoryManager != NULL) { - if (m_HostMalloc == NULL) - { - hr = memoryManager->CreateMalloc (MALLOC_THREADSAFE, &m_HostMalloc); - if (hr == S_OK) - { - memoryManager->RegisterMemoryNotificationCallback(&s_MemoryNotification); - } - else - { - memoryManager->Release(); - IfFailGo(E_UNEXPECTED); - } - } - m_HostMemoryManager = memoryManager; - g_fHostConfig |= CLRMEMORYHOSTED; - } - - if (m_HostTaskManager == NULL && -#ifdef _DEBUG - (dbg_HostManagerConfig & CLRTASKHOSTED) && -#endif - pHostControl->GetHostManager(IID_IHostTaskManager,(void**)&taskManager) == S_OK && - taskManager != NULL) { -#ifdef _TARGET_ARM_ // @ARMTODO: re-enable once we support hosted p/invokes. - IfFailGo(E_NOTIMPL); -#endif - m_HostTaskManager = taskManager; - m_HostTaskManager->SetCLRTaskManager(&s_CLRTaskManager); - g_fHostConfig |= CLRTASKHOSTED; - } - - if (m_HostThreadpoolManager == NULL && -#ifdef _DEBUG - (dbg_HostManagerConfig & CLRTHREADPOOLHOSTED) && -#endif - pHostControl->GetHostManager(IID_IHostThreadpoolManager,(void**)&threadpoolManager) == S_OK && - threadpoolManager != NULL) { - m_HostThreadpoolManager = threadpoolManager; - g_fHostConfig |= CLRTHREADPOOLHOSTED; - } - - if (m_HostIoCompletionManager == NULL && -#ifdef _DEBUG - (dbg_HostManagerConfig & CLRIOCOMPLETIONHOSTED) && -#endif - pHostControl->GetHostManager(IID_IHostIoCompletionManager,(void**)&ioCompletionManager) == S_OK && - ioCompletionManager != NULL) { - DWORD hostSize; - hr = ioCompletionManager->GetHostOverlappedSize(&hostSize); - if (FAILED(hr)) - { - ioCompletionManager->Release(); - IfFailGo(E_UNEXPECTED); - } - m_HostOverlappedExtensionSize = (int)hostSize; - m_HostIoCompletionManager = ioCompletionManager; - m_HostIoCompletionManager->SetCLRIoCompletionManager(&s_CLRIoCompletionManager); - g_fHostConfig |= CLRIOCOMPLETIONHOSTED; - } - - if (m_HostSyncManager == NULL && -#ifdef _DEBUG - (dbg_HostManagerConfig & CLRSYNCHOSTED) && -#endif - pHostControl->GetHostManager(IID_IHostSyncManager,(void**)&syncManager) == S_OK && - syncManager != NULL) { - m_HostSyncManager = syncManager; - m_HostSyncManager->SetCLRSyncManager(&s_CLRSyncManager); - g_fHostConfig |= CLRSYNCHOSTED; - } - - if (m_HostAssemblyManager == NULL && -#ifdef _DEBUG - (dbg_HostManagerConfig & CLRASSEMBLYHOSTED) && -#endif - pHostControl->GetHostManager(IID_IHostAssemblyManager,(void**)&assemblyManager) == S_OK && - assemblyManager != NULL) { - - assemblyManager->GetAssemblyStore(&g_pHostAssemblyStore); - - hr = assemblyManager->GetNonHostStoreAssemblies(&g_pHostAsmList); - if (FAILED(hr)) - { - assemblyManager->Release(); - IfFailGo(hr); - } - - if (g_pHostAssemblyStore || g_pHostAsmList) - g_bFusionHosted = TRUE; - m_HostAssemblyManager = assemblyManager; - g_fHostConfig |= CLRASSEMBLYHOSTED; - } - - if (m_HostGCManager == NULL && -#ifdef _DEBUG - (dbg_HostManagerConfig & CLRGCHOSTED) && -#endif - pHostControl->GetHostManager(IID_IHostGCManager, - (void**)&gcManager) == S_OK && - gcManager != NULL) { - m_HostGCManager = gcManager; - g_fHostConfig |= CLRGCHOSTED; - } - - if (m_HostSecurityManager == NULL && -#ifdef _DEBUG - (dbg_HostManagerConfig & CLRSECURITYHOSTED) && -#endif - pHostControl->GetHostManager(IID_IHostSecurityManager, - (void**)&securityManager) == S_OK && - securityManager != NULL) { - g_fHostConfig |= CLRSECURITYHOSTED; - m_HostSecurityManager = securityManager; -#ifdef FEATURE_CAS_POLICY - HostExecutionContextManager::InitializeRestrictedContext(); -#endif // #ifdef FEATURE_CAS_POLICY - } - - if (m_HostPolicyManager == NULL && - pHostControl->GetHostManager(IID_IHostPolicyManager, - (void**)&policyManager) == S_OK && - policyManager != NULL) { - m_HostPolicyManager = policyManager; - } -#endif //!FEATURE_CORECLR if (m_HostControl == NULL) { @@ -4574,64 +1623,28 @@ public: EPolicyAction action) { LIMITED_METHOD_CONTRACT; -#ifndef FEATURE_CORECLR - STATIC_CONTRACT_ENTRY_POINT; - HRESULT hr; - BEGIN_ENTRYPOINT_NOTHROW; - hr = GetEEPolicy()->SetDefaultAction(operation, action); - END_ENTRYPOINT_NOTHROW; - return hr; -#else // FEATURE_CORECLR return E_NOTIMPL; -#endif // !FEATURE_CORECLR } virtual HRESULT STDMETHODCALLTYPE SetTimeout(EClrOperation operation, DWORD dwMilliseconds) { LIMITED_METHOD_CONTRACT; -#ifndef FEATURE_CORECLR - STATIC_CONTRACT_ENTRY_POINT; - HRESULT hr; - BEGIN_ENTRYPOINT_NOTHROW; - hr = GetEEPolicy()->SetTimeout(operation,dwMilliseconds); - END_ENTRYPOINT_NOTHROW; - return hr; -#else // FEATURE_CORECLR return E_NOTIMPL; -#endif // !FEATURE_CORECLR } virtual HRESULT STDMETHODCALLTYPE SetActionOnTimeout(EClrOperation operation, EPolicyAction action) { LIMITED_METHOD_CONTRACT; -#ifndef FEATURE_CORECLR - STATIC_CONTRACT_ENTRY_POINT; - HRESULT hr; - BEGIN_ENTRYPOINT_NOTHROW; - hr = GetEEPolicy()->SetActionOnTimeout(operation,action); - END_ENTRYPOINT_NOTHROW; - return hr; -#else // FEATURE_CORECLR return E_NOTIMPL; -#endif // !FEATURE_CORECLR } virtual HRESULT STDMETHODCALLTYPE SetTimeoutAndAction(EClrOperation operation, DWORD dwMilliseconds, EPolicyAction action) { LIMITED_METHOD_CONTRACT; -#ifndef FEATURE_CORECLR - STATIC_CONTRACT_SO_TOLERANT; - HRESULT hr; - BEGIN_ENTRYPOINT_NOTHROW; - hr = GetEEPolicy()->SetTimeoutAndAction(operation,dwMilliseconds,action); - END_ENTRYPOINT_NOTHROW; - return hr; -#else // FEATURE_CORECLR return E_NOTIMPL; -#endif // !FEATURE_CORECLR } virtual HRESULT STDMETHODCALLTYPE SetActionOnFailure(EClrFailure failure, @@ -4642,7 +1655,6 @@ public: STATIC_CONTRACT_ENTRY_POINT; LIMITED_METHOD_CONTRACT; HRESULT hr; -#ifdef FEATURE_CORECLR // For CoreCLR, this method just supports FAIL_AccessViolation as a valid // failure input arg. The validation of the specified action for the failure // will be done in EEPolicy::IsValidActionForFailure. @@ -4650,7 +1662,6 @@ public: { return E_INVALIDARG; } -#endif // FEATURE_CORECLR BEGIN_ENTRYPOINT_NOTHROW; hr = GetEEPolicy()->SetActionOnFailure(failure,action); END_ENTRYPOINT_NOTHROW; @@ -4660,16 +1671,7 @@ public: virtual HRESULT STDMETHODCALLTYPE SetUnhandledExceptionPolicy(EClrUnhandledException policy) { LIMITED_METHOD_CONTRACT; -#ifndef FEATURE_CORECLR - STATIC_CONTRACT_ENTRY_POINT; - HRESULT hr; - BEGIN_ENTRYPOINT_NOTHROW; - hr = GetEEPolicy()->SetUnhandledExceptionPolicy(policy); - END_ENTRYPOINT_NOTHROW; - return hr; -#else // FEATURE_CORECLR return E_NOTIMPL; -#endif // !FEATURE_CORECLR } virtual ULONG STDMETHODCALLTYPE AddRef(void) @@ -4705,427 +1707,22 @@ public: static CCLRPolicyManager s_PolicyManager; -#ifndef FEATURE_CORECLR // not supported -class CCLROnEventManager: public ICLROnEventManager -{ -public: - virtual HRESULT STDMETHODCALLTYPE RegisterActionOnEvent(EClrEvent event, - IActionOnCLREvent *pAction) - { - CONTRACTL - { - GC_TRIGGERS; - NOTHROW; - ENTRY_POINT; - - // This function is always called from outside the Runtime. So, we assert that we either don't have a - // managed thread, or if we do, that we're in preemptive GC mode. - PRECONDITION((GetThread() == NULL) || !GetThread()->PreemptiveGCDisabled()); - } - CONTRACTL_END; - - if (event >= MaxClrEvent || pAction == NULL || event < (EClrEvent)0) - return E_INVALIDARG; - - HRESULT hr = S_OK; - BEGIN_ENTRYPOINT_NOTHROW; - - // Note: its only safe to use a straight ReleaseHolder from within the VM directory when we know we're - // called from outside the Runtime. We assert that above, just to be sure. - ReleaseHolder<IActionOnCLREvent> actionHolder(pAction); - pAction->AddRef(); - - CrstHolderWithState ch(m_pLock); - - DWORD dwSwitchCount = 0; - while (m_ProcessEvent != 0) - { - ch.Release(); - __SwitchToThread(0, ++dwSwitchCount); - ch.Acquire(); - } - - if (m_pAction[event] == NULL) - { - m_pAction[event] = new (nothrow)ActionNode; - if (m_pAction[event] == NULL) - hr = E_OUTOFMEMORY; - } - - if (SUCCEEDED(hr)) - { - ActionNode *walk = m_pAction[event]; - while (TRUE) - { - int n = 0; - for ( ; n < ActionNode::ActionArraySize; n ++) - { - if (walk->pAction[n] == NULL) - { - walk->pAction[n] = pAction; - actionHolder.SuppressRelease(); - hr = S_OK; - break; - } - } - if (n < ActionNode::ActionArraySize) - { - break; - } - if (walk->pNext == NULL) - { - walk->pNext = new (nothrow) ActionNode; - if (walk->pNext == NULL) - { - hr = E_OUTOFMEMORY; - break; - } - } - walk = walk->pNext; - } - } - - END_ENTRYPOINT_NOTHROW; - return hr; - } - - virtual HRESULT STDMETHODCALLTYPE UnregisterActionOnEvent(EClrEvent event, - IActionOnCLREvent *pAction) - { - CONTRACTL - { - GC_NOTRIGGER; - NOTHROW; - ENTRY_POINT; - } - CONTRACTL_END; - - if (event == Event_StackOverflow) - { - // We don't want to take a lock when we process StackOverflow event, because we may - // not have enough stack to do it. - // So we do not release our cache of the callback in order to avoid race. - return HOST_E_INVALIDOPERATION; - } - - HRESULT hr = S_OK; - - ActionNode *walk = NULL; - ActionNode *prev = NULL; - - - BEGIN_ENTRYPOINT_NOTHROW; - - CrstHolderWithState ch(m_pLock); - - DWORD dwSwitchCount = 0; - while (m_ProcessEvent != 0) - { - ch.Release(); - __SwitchToThread(0, ++dwSwitchCount); - ch.Acquire(); - } - - if (m_pAction[event] == NULL) - IfFailGo(HOST_E_INVALIDOPERATION); - - walk = m_pAction[event]; - while (walk) - { - BOOL fInUse = FALSE; - for (int n = 0; n < ActionNode::ActionArraySize; n ++) - { - if (prev && !fInUse && walk->pAction[n]) - fInUse = TRUE; - if (walk->pAction[n] == pAction) - { - walk->pAction[n] = NULL; - ch.Release(); - pAction->Release(); - hr = S_OK; - goto ErrExit; - } - } - if (prev && !fInUse) - { - prev->pNext = walk->pNext; - delete walk; - walk = prev; - } - prev = walk; - walk = walk->pNext; - } - hr = HOST_E_INVALIDOPERATION; -ErrExit: - END_ENTRYPOINT_NOTHROW; - - return hr; - } - - virtual ULONG STDMETHODCALLTYPE AddRef(void) - { - STATIC_CONTRACT_SO_TOLERANT; - LIMITED_METHOD_CONTRACT; - return 1; - } - - virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppUnk) - { - STATIC_CONTRACT_SO_TOLERANT; - LIMITED_METHOD_CONTRACT; - if (riid != IID_ICLROnEventManager && riid != IID_IUnknown) - return (E_NOINTERFACE); - *ppUnk = this; - return S_OK; - } - - virtual ULONG STDMETHODCALLTYPE Release(void) - { - STATIC_CONTRACT_SO_TOLERANT; - LIMITED_METHOD_CONTRACT; - return 1; - } - - // This function is to work around an issue in scan.exe. - // scan.exe is not smart to handle that if (){} else {}. - void ProcessSOEvent(void *data) - { - STATIC_CONTRACT_SO_TOLERANT; - WRAPPER_NO_CONTRACT; - - if (m_pLock == NULL) - return; - - ActionNode *walk = m_pAction[Event_StackOverflow]; - - while (walk) - { - for (int n = 0; n < ActionNode::ActionArraySize; n ++) - { - if (walk->pAction[n]) - { - walk->pAction[n]->OnEvent(Event_StackOverflow,data); - } - } - walk = walk->pNext; - } - } - - void ProcessEvent(EClrEvent event, void *data) - { - WRAPPER_NO_CONTRACT; - - if (m_pLock == NULL) - { - return; - } - - _ASSERTE (event != Event_StackOverflow); - - { - CrstHolder ch(m_pLock); - - if (event == Event_ClrDisabled) - { - if (m_CLRDisabled) - { - return; - } - m_CLRDisabled = TRUE; - } - m_ProcessEvent ++; - - // Release the lock around the call into the host. Is this correct? - // It seems that we need to hold the lock except for the actual callback itself. - } - - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - { - ActionNode *walk = m_pAction[event]; - while (walk) - { - for (int n = 0; n < ActionNode::ActionArraySize; n ++) - { - if (walk->pAction[n]) - { - walk->pAction[n]->OnEvent(event,data); - } - } - walk = walk->pNext; - } - } - END_SO_TOLERANT_CODE_CALLING_HOST; - - { - CrstHolder ch(m_pLock); - m_ProcessEvent --; - } - } - - BOOL IsActionRegisteredForEvent(EClrEvent event) - { - WRAPPER_NO_CONTRACT; - - // Check to see if the event manager has been set up. - if (m_pLock == NULL) - return FALSE; - - CrstHolder ch(m_pLock); - - ActionNode *walk = m_pAction[event]; - while (walk) - { - for (int n = 0; n < ActionNode::ActionArraySize; n ++) - { - if (walk->pAction[n] != NULL) - { - // We found an action registered for this event. - return TRUE; - } - } - walk = walk->pNext; - } - - // There weren't any actions registered. - return FALSE; - } - - HRESULT Init() - { - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_MODE_ANY; - STATIC_CONTRACT_SO_TOLERANT; - - HRESULT hr = S_OK; - if (m_pLock == NULL) - { - EX_TRY - { - BEGIN_SO_INTOLERANT_CODE(GetThread()); - { - InitHelper(); - } - END_SO_INTOLERANT_CODE; - } - EX_CATCH - { - hr = GET_EXCEPTION()->GetHR(); - } - EX_END_CATCH(SwallowAllExceptions); - } - - return hr; - } - -#if 0 - // We do not need this one. We have one instance of this class - // and it is static. - CCLROnEventManager() - { - LIMITED_METHOD_CONTRACT; - for (int n = 0; n < MaxClrEvent; n ++) - m_pAction[n] = NULL; - } -#endif - -private: - struct ActionNode - { - static const int ActionArraySize = 8; - - IActionOnCLREvent *pAction[ActionArraySize]; - ActionNode *pNext; - - ActionNode () - : pNext(NULL) - { - LIMITED_METHOD_CONTRACT; - - for (int n = 0; n < ActionArraySize; n ++) - pAction[n] = 0; - } - }; - ActionNode *m_pAction[MaxClrEvent]; - - Crst* m_pLock; - - BOOL m_CLRDisabled; - - // We can not call out into host while holding the lock. At the same time - // we need to make our data consistent. Therefore, m_ProcessEvent is a marker - // to forbid touching the data structure from Register and UnRegister. - DWORD m_ProcessEvent; - - void InitHelper() - { - CONTRACTL - { - GC_NOTRIGGER; - THROWS; - MODE_ANY; - } - CONTRACTL_END; - - m_ProcessEvent = 0; - - Crst* tmp = new Crst(CrstOnEventManager, CrstFlags(CRST_DEFAULT | CRST_DEBUGGER_THREAD)); - if (FastInterlockCompareExchangePointer(&m_pLock, tmp, NULL) != NULL) - delete tmp; - } -}; - -static CCLROnEventManager s_OnEventManager; -#endif // FEATURE_CORECLR void ProcessEventForHost(EClrEvent event, void *data) { -#ifndef FEATURE_CORECLR - WRAPPER_NO_CONTRACT; - - _ASSERTE (event != Event_StackOverflow); - - GCX_PREEMP(); - - s_OnEventManager.ProcessEvent(event,data); -#endif // FEATURE_CORECLR } // We do not call ProcessEventForHost for stack overflow, since we have limit stack // and we should avoid calling GCX_PREEMPT void ProcessSOEventForHost(EXCEPTION_POINTERS *pExceptionInfo, BOOL fInSoTolerant) { -#ifndef FEATURE_CORECLR - WRAPPER_NO_CONTRACT; - - StackOverflowInfo soInfo; - if (fInSoTolerant) - { - soInfo.soType = SO_Managed; - } - else if (pExceptionInfo == NULL || IsIPInModule(g_pMSCorEE, GetIP(pExceptionInfo->ContextRecord))) - { - soInfo.soType = SO_ClrEngine; - } - else - { - soInfo.soType = SO_Other; - } - - soInfo.pExceptionInfo = pExceptionInfo; - s_OnEventManager.ProcessSOEvent(&soInfo); -#endif // FEATURE_CORECLR } BOOL IsHostRegisteredForEvent(EClrEvent event) { WRAPPER_NO_CONTRACT; -#ifdef FEATURE_CORECLR return FALSE; -#else // FEATURE_CORECLR - return s_OnEventManager.IsActionRegisteredForEvent(event); -#endif // FEATURE_CORECLR } inline size_t SizeInKBytes(size_t cbSize) @@ -5154,7 +1751,7 @@ void UpdateGCSettingFromHost () } } -#if !defined(FEATURE_CORECLR) || defined(FEATURE_WINDOWSPHONE) +#if defined(FEATURE_WINDOWSPHONE) class CCLRGCManager: public ICLRGCManager2 { public: @@ -5394,7 +1991,7 @@ HRESULT CCLRGCManager::_SetGCMaxGen0Size(SIZE_T MaxGen0Size) } static CCLRGCManager s_GCManager; -#endif // !FEATURE_CORECLR || FEATURE_WINDOWSPHONE +#endif //FEATURE_WINDOWSPHONE #ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING class CCLRAppDomainResourceMonitor : public ICLRAppDomainResourceMonitor @@ -5542,92 +2139,6 @@ public: static CCLRAppDomainResourceMonitor s_Arm; #endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING -#ifdef FEATURE_APTCA -class CLRDomainManager : public ICLRDomainManager -{ -public: - virtual HRESULT STDMETHODCALLTYPE SetAppDomainManagerType(__in LPCWSTR wszAppDomainManagerAssembly, - __in LPCWSTR wszAppDomainManagerType, - EInitializeNewDomainFlags dwInitializeDomainFlags) - { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - BEGIN_ENTRYPOINT_NOTHROW; - - hr = CorHost2::SetAppDomainManagerType(wszAppDomainManagerAssembly, - wszAppDomainManagerType, - dwInitializeDomainFlags); - END_ENTRYPOINT_NOTHROW; - return hr; - } - - virtual HRESULT STDMETHODCALLTYPE SetPropertiesForDefaultAppDomain(DWORD nProperties, - __in_ecount(nProperties) LPCWSTR *pwszPropertyNames, - __in_ecount(nProperties) LPCWSTR *pwszPropertyValues) - { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - BEGIN_ENTRYPOINT_NOTHROW; - - hr = CorHost2::SetPropertiesForDefaultAppDomain(nProperties, pwszPropertyNames, pwszPropertyValues); - - END_ENTRYPOINT_NOTHROW; - return hr; - } - - virtual ULONG STDMETHODCALLTYPE AddRef() - { - LIMITED_METHOD_CONTRACT; - return 1; - } - - virtual ULONG STDMETHODCALLTYPE Release() - { - LIMITED_METHOD_CONTRACT; - return 1; - } - - virtual HRESULT STDMETHODCALLTYPE QueryInterface(__in REFIID riid, __out LPVOID *ppvObject) - { - LIMITED_METHOD_CONTRACT; - - if (ppvObject == NULL) - return E_POINTER; - - *ppvObject = NULL; - - if (riid == IID_ICLRDomainManager) - { - *ppvObject = this; - } - else if (riid == IID_IUnknown) - { - *ppvObject = static_cast<IUnknown *>(this); - } - - if (*ppvObject == NULL) - return E_NOINTERFACE; - - AddRef(); - return S_OK; - } -}; - -static CLRDomainManager s_CLRDomainManager; -#endif // FEATURE_APTCA BOOL g_CLRPolicyRequested = FALSE; @@ -5648,35 +2159,19 @@ public: if (ppObject == NULL) return E_INVALIDARG; -#ifndef FEATURE_CORECLR - // ErrorReportingManager is allowed, even if runtime is started, so - // make this check first. - // Host must call release on CLRErrorReportingManager after this call - if (riid == IID_ICLRErrorReportingManager) - { - *ppObject = &g_CLRErrorReportingManager; - return S_OK; - } - else -#elif defined(FEATURE_WINDOWSPHONE) +#if defined(FEATURE_WINDOWSPHONE) if (riid == IID_ICLRErrorReportingManager2) { *ppObject = &g_CLRErrorReportingManager; return S_OK; } else -#endif // !FEATURE_CORECLR || defined(FEATURE_WINDOWSPHONE) +#endif //defined(FEATURE_WINDOWSPHONE) if (g_fEEStarted && !m_fFullAccess) { // If runtime has been started, do not allow user to obtain CLR managers. return HOST_E_INVALIDOPERATION; } -#ifndef FEATURE_CORECLR - else if (riid == IID_ICLRTaskManager) { - *ppObject = &s_CLRTaskManager; - return S_OK; - } -#endif // !FEATURE_CORECLR // CoreCLR supports ICLRPolicyManager since it allows the host // to specify the policy for AccessViolation. @@ -5685,36 +2180,14 @@ public: FastInterlockExchange((LONG*)&g_CLRPolicyRequested, TRUE); return S_OK; } -#ifndef FEATURE_CORECLR - else if (riid == IID_ICLRHostProtectionManager) { - *ppObject = GetHostProtectionManager(); - return S_OK; - } - - // Host must call release on CLRDebugManager after this call - else if (riid == IID_ICLRDebugManager) - { - *ppObject = &s_CLRDebugManager; - return S_OK; - } - else if (riid == IID_ICLROnEventManager) - { - HRESULT hr = s_OnEventManager.Init(); - if (FAILED(hr)) - return hr; - *ppObject = &s_OnEventManager; - return S_OK; - } -#endif // !FEATURE_CORECLR - -#if !defined(FEATURE_CORECLR) || defined(FEATURE_WINDOWSPHONE) +#if defined(FEATURE_WINDOWSPHONE) else if ((riid == IID_ICLRGCManager) || (riid == IID_ICLRGCManager2)) { *ppObject = &s_GCManager; return S_OK; } -#endif // !FEATURE_CORECLR || FEATURE_WINDOWSPHONE +#endif //FEATURE_WINDOWSPHONE #ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING else if (riid == IID_ICLRAppDomainResourceMonitor) @@ -5724,13 +2197,6 @@ public: return S_OK; } #endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING -#ifdef FEATURE_APTCA - else if (riid == IID_ICLRDomainManager) - { - *ppObject = &s_CLRDomainManager; - return S_OK; - } -#endif // FEATURE_APTCA else return (E_NOINTERFACE); } @@ -5739,29 +2205,9 @@ public: LPCWSTR pwzAppDomainManagerAssembly, LPCWSTR pwzAppDomainManagerType) { -#ifndef FEATURE_CORECLR - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - ENTRY_POINT; // no global state updates - } - CONTRACTL_END; - - HRESULT hr = S_OK; - - BEGIN_ENTRYPOINT_NOTHROW; - - hr = CorHost2::SetAppDomainManagerType(pwzAppDomainManagerAssembly, - pwzAppDomainManagerType, - eInitializeNewDomainFlags_None); - END_ENTRYPOINT_NOTHROW; - return hr; -#else // FEATURE_CORECLR // CoreCLR does not support this method return E_NOTIMPL; -#endif // !FEATURE_CORECLR } virtual ULONG STDMETHODCALLTYPE AddRef(void) @@ -5806,9 +2252,6 @@ private: // After CLR starts, we give out s_CorCLRControlLimited which allows limited access to managers. static CCorCLRControl s_CorCLRControl; -#ifndef FEATURE_CORECLR -static CCorCLRControl s_CorCLRControlLimited; -#endif // FEATURE_CORECLR /////////////////////////////////////////////////////////////////////////////// // ICLRRuntimeHost::GetCLRControl @@ -5833,11 +2276,6 @@ HRESULT CorHost2::GetCLRControl(ICLRControl** pCLRControl) } else { -#ifndef FEATURE_CORECLR - // Even CLR is hosted by v1 hosting interface, we still allow part of CLRControl, like IID_ICLRErrorReportingManager. - s_CorCLRControlLimited.SetAccess(FALSE); - *pCLRControl = &s_CorCLRControlLimited; -#else // FEATURE_CORECLR // If : // 1) request comes for interface other than ICLRControl*, OR // 2) runtime has already started, OR @@ -5854,647 +2292,45 @@ HRESULT CorHost2::GetCLRControl(ICLRControl** pCLRControl) { hr = E_NOTIMPL; } -#endif // !FEATURE_CORECLR } END_ENTRYPOINT_NOTHROW; return hr; } -#ifndef FEATURE_CORECLR - -// static -HRESULT CorHost2::SetPropertiesForDefaultAppDomain(DWORD nProperties, - __in_ecount(nProperties) LPCWSTR *pwszPropertyNames, - __in_ecount(nProperties) LPCWSTR *pwszPropertyValues) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - // Default domain properties can only be set before the CLR has started - if (g_fEEStarted || HasStarted()) - { - return HOST_E_INVALIDOPERATION; - } - - // If the host is specifying properties, they should be there - if (nProperties > 0 && (pwszPropertyNames == NULL || pwszPropertyValues == NULL)) - { - return E_POINTER; - } - - // v4 - since this property is being added late in the cycle to address a specific scenario, we - // reject any attempt to set anything but a single well known property name. This restriction - // can be removed in the future. - for (DWORD iProperty = 0; iProperty < nProperties; ++iProperty) - { - if (pwszPropertyNames[iProperty] == NULL) - { - return E_POINTER; - } - if (pwszPropertyValues[iProperty] == NULL) - { - return E_POINTER; - } - if (wcscmp(PARTIAL_TRUST_VISIBLE_ASSEMBLIES_PROPERTY, pwszPropertyNames[iProperty]) != 0) - { - return HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY); - } - } - - HRESULT hr = S_OK; - - EX_TRY - { - for (DWORD iProperty = 0; iProperty < nProperties; ++iProperty) - { - SString propertyName(pwszPropertyNames[iProperty]); - s_defaultDomainPropertyNames.Append(propertyName); - - SString propertyValue(pwszPropertyValues[iProperty]); - s_defaultDomainPropertyValues.Append(propertyValue); - } - } - EX_CATCH_HRESULT(hr); - - return hr; -} - -// static -HRESULT CorHost2::SetAppDomainManagerType(LPCWSTR wszAppDomainManagerAssembly, - LPCWSTR wszAppDomainManagerType, - EInitializeNewDomainFlags dwInitializeDomainFlags) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - } - CONTRACTL_END; - - // The AppDomainManger can only be set by the host before the CLR has started - if (g_fEEStarted || HasStarted()) - { - return HOST_E_INVALIDOPERATION; - } - - // Both the type and assembly must be specified - if (wszAppDomainManagerAssembly == NULL || wszAppDomainManagerType == NULL) - { - return E_INVALIDARG; - } - - // Make sure we understand the incoming flags - const EInitializeNewDomainFlags knownFlags = eInitializeNewDomainFlags_NoSecurityChanges; - if ((dwInitializeDomainFlags & (~knownFlags)) != eInitializeNewDomainFlags_None) - { - return E_INVALIDARG; - } - - // Get a copy of the AppDomainManager assembly - size_t cchAsm = wcslen(wszAppDomainManagerAssembly) + 1; - NewArrayHolder<WCHAR> wszAppDomainManagerAssemblyCopy(new (nothrow) WCHAR[cchAsm]); - if (wszAppDomainManagerAssemblyCopy == NULL) - { - return E_OUTOFMEMORY; - } - wcsncpy_s(wszAppDomainManagerAssemblyCopy, cchAsm, wszAppDomainManagerAssembly, cchAsm - 1); - - // And of the AppDomainManagerType - size_t cchType = wcslen(wszAppDomainManagerType) + 1; - NewArrayHolder<WCHAR> wszAppDomainManagerTypeCopy(new (nothrow) WCHAR[cchType]); - if (wszAppDomainManagerTypeCopy == NULL) - { - return E_OUTOFMEMORY; - } - wcsncpy_s(wszAppDomainManagerTypeCopy, cchType, wszAppDomainManagerType, cchType - 1); - - LPCWSTR wszOldAsmValue = FastInterlockCompareExchangePointer(&s_wszAppDomainManagerAsm, - static_cast<LPCWSTR>(wszAppDomainManagerAssemblyCopy.GetValue()), - NULL); - if (wszOldAsmValue != NULL) - { - // We've tried to setup an AppDomainManager twice ... that's not allowed - return HOST_E_INVALIDOPERATION; - } - - s_wszAppDomainManagerType = wszAppDomainManagerTypeCopy; - s_dwDomainManagerInitFlags = dwInitializeDomainFlags; - - wszAppDomainManagerAssemblyCopy.SuppressRelease(); - wszAppDomainManagerTypeCopy.SuppressRelease(); - return S_OK; -} -#endif // !FEATURE_CORECLR LPCWSTR CorHost2::GetAppDomainManagerAsm() { LIMITED_METHOD_CONTRACT; -#ifdef FEATURE_CORECLR return NULL; -#else // FEATURE_CORECLR - _ASSERTE (g_fEEStarted); - return s_wszAppDomainManagerAsm; -#endif // FEATURE_CORECLR } LPCWSTR CorHost2::GetAppDomainManagerType() { LIMITED_METHOD_CONTRACT; -#ifdef FEATURE_CORECLR return NULL; -#else // FEATURE_CORECLR - _ASSERTE (g_fEEStarted); - return s_wszAppDomainManagerType; -#endif // FEATURE_CORECLR } // static EInitializeNewDomainFlags CorHost2::GetAppDomainManagerInitializeNewDomainFlags() { LIMITED_METHOD_CONTRACT; -#ifdef FEATURE_CORECLR return eInitializeNewDomainFlags_None; -#else // FEAUTRE_CORECLR - _ASSERTE (g_fEEStarted); - return s_dwDomainManagerInitFlags; -#endif // FEATURE_CORECLR -} - -#ifdef FEATURE_INCLUDE_ALL_INTERFACES -// We do not implement the Release since our host does not control the lifetime on this object -ULONG CCLRDebugManager::Release() -{ - LIMITED_METHOD_CONTRACT; - return (1); -} - -HRESULT CCLRDebugManager::QueryInterface(REFIID riid, void **ppUnk) -{ - if (!ppUnk) - return E_POINTER; - - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - SO_TOLERANT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - - if (ppUnk == NULL) - { - return E_POINTER; - } - - *ppUnk = 0; - - // Deliberately do NOT hand out ICorConfiguration. They must explicitly call - // GetConfiguration to obtain that interface. - if (riid == IID_IUnknown) - { - *ppUnk = (IUnknown *) this; - } - else if (riid == IID_ICLRDebugManager) - { - *ppUnk = (ICLRDebugManager *) this; - } - else - { - hr = E_NOINTERFACE; - } - - return hr; - -} - -/* -* -* Called once to when process start up to initialize the lock for connection name hash table -* -*/ -void CCLRDebugManager::ProcessInit() -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - } - CONTRACTL_END; - - m_lockConnectionNameTable.Init(CrstConnectionNameTable, (CrstFlags) (CRST_UNSAFE_ANYMODE | CRST_DEBUGGER_THREAD)); } -/* -* Called once to when process shut down to destroy the lock for connection name hash table -* -*/ -void CCLRDebugManager::ProcessCleanup() -{ - CONTRACTL - { - GC_NOTRIGGER; - NOTHROW; - } - CONTRACTL_END; - - m_lockConnectionNameTable.Destroy(); -} -#endif // FEATURE_INCLUDE_ALL_INTERFACES #endif // !DAC #ifdef DACCESS_COMPILE -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - -//--------------------------------------------------------------------------------------- -// Begin an iterating over connections for Debugger -// -// Arguments: -// pHashfind - out: initializes cookie to pass to to future calls to code:CCLRDebugManager.FindNext -// -// Returns: -// NULL if iteration is done. Else a ConnectionNameHashEntry representing the connection. -// -ConnectionNameHashEntry * CCLRDebugManager::FindFirst(HASHFIND * pHashfind) -{ - SUPPORTS_DAC; - if (m_pConnectionNameHash == NULL) - { - return NULL; - } - - ConnectionNameHashEntry * pConnection = dac_cast<PTR_ConnectionNameHashEntry>(m_pConnectionNameHash->FindFirstEntry(pHashfind)); - return pConnection; - } - -//--------------------------------------------------------------------------------------- -// Begin an iterating over connections for Debugger -// -// Arguments: -// pHashfind - in/out: iterator cookie to pass to future calls to code:CCLRDebugManager.FindNext -// -// Returns: -// NULL if iteration is done. Else a ConnectionNameHashEntry representing the connection. -// -ConnectionNameHashEntry * CCLRDebugManager::FindNext(HASHFIND * pHashfind) - { - SUPPORTS_DAC; - ConnectionNameHashEntry * pConnection = dac_cast<PTR_ConnectionNameHashEntry>(m_pConnectionNameHash->FindNextEntry(pHashfind)); - return pConnection; -} - -#endif // FEATURE_INCLUDE_ALL_INTERFACES #endif //DACCESS_COMPILE #ifndef DACCESS_COMPILE -#ifdef FEATURE_INCLUDE_ALL_INTERFACES -HRESULT CCLRDebugManager::IsDebuggerAttached(BOOL *pbAttached) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - ENTRY_POINT; - } - CONTRACTL_END; - - if (pbAttached == NULL) - return E_INVALIDARG; - - BEGIN_ENTRYPOINT_NOTHROW; - -#ifdef DEBUGGING_SUPPORTED - *pbAttached = (CORDebuggerAttached() != 0); -#else - *pbAttached = FALSE; -#endif - - END_ENTRYPOINT_NOTHROW; - - - return S_OK; -} - -// By default, we permit symbols to be read for full-trust assemblies only -ESymbolReadingSetBy CCLRDebugManager::m_symbolReadingSetBy = eSymbolReadingSetByDefault; -ESymbolReadingPolicy CCLRDebugManager::m_symbolReadingPolicy = eSymbolReadingFullTrustOnly; - -HRESULT CCLRDebugManager::SetSymbolReadingPolicy(ESymbolReadingPolicy policy) -{ - LIMITED_METHOD_CONTRACT; - STATIC_CONTRACT_ENTRY_POINT; - - if( policy > eSymbolReadingFullTrustOnly ) - { - return E_INVALIDARG; - } - - SetSymbolReadingPolicy( policy, eSymbolReadingSetByHost ); - - return S_OK; -} - -void CCLRDebugManager::SetSymbolReadingPolicy( ESymbolReadingPolicy policy, ESymbolReadingSetBy setBy ) -{ - LIMITED_METHOD_CONTRACT; - _ASSERTE( policy <= eSymbolReadingFullTrustOnly ); // don't have _COUNT because it's not in convention for mscoree.idl enums - _ASSERTE( setBy < eSymbolReadingSetBy_COUNT ); - - // if the setter meets or exceeds the precendence of the existing setting then override the setting - if( setBy >= m_symbolReadingSetBy ) - { - m_symbolReadingSetBy = setBy; - m_symbolReadingPolicy = policy; - } -} - - -/* -* Call by host to set the name of a connection and begin a connection. -* -*/ -HRESULT CCLRDebugManager::BeginConnection( - CONNID dwConnectionId, - __in_z wchar_t *wzConnectionName) // We should review this in the future. This API is - // public and callable by a host. This SAL annotation - // is the best we can do now. -{ - CONTRACTL - { - GC_TRIGGERS; // I am having problem in putting either GC_TRIGGERS or GC_NOTRIGGER. It is not happy either way when debugger - // call back event needs to enable preemptive GC. - ENTRY_POINT; - NOTHROW; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - BEGIN_ENTRYPOINT_NOTHROW; - - ConnectionNameHashEntry *pEntry = NULL; - - // check input parameter - if (dwConnectionId == INVALID_CONNECTION_ID || wzConnectionName == NULL || wzConnectionName[0] == W('\0')) - IfFailGo(E_INVALIDARG); - - if (wcslen(wzConnectionName) >= MAX_CONNECTION_NAME) - IfFailGo(E_INVALIDARG); - - { - CrstHolder ch(&m_lockConnectionNameTable); - - if (m_pConnectionNameHash == NULL) - { - m_pConnectionNameHash = new (nothrow) ConnectionNameTable(50); - IfNullGo(m_pConnectionNameHash); - IfFailGo(m_pConnectionNameHash->NewInit(50, sizeof(ConnectionNameHashEntry), USHRT_MAX)); - } - - // error: Should not have an existing connection id already - if (m_pConnectionNameHash->FindConnection(dwConnectionId)) - IfFailGo(E_INVALIDARG); - - // Our implementation of hashtable cannot throw out of memory exception - pEntry = m_pConnectionNameHash->AddConnection(dwConnectionId, wzConnectionName); - IfNullGo(pEntry); - } - - // send notification to debugger - if (CORDebuggerAttached()) - { - g_pDebugInterface->CreateConnection(dwConnectionId, wzConnectionName); - } - -ErrExit: - END_ENTRYPOINT_NOTHROW; - - return hr; -} - -/* -* Call by host to end a connection -*/ -HRESULT CCLRDebugManager::EndConnection(CONNID dwConnectionId) -{ - CONTRACTL - { - GC_TRIGGERS; - NOTHROW; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - UINT CLRTaskCount = 0; - ICLRTask **ppCLRTaskArray = NULL; - - BEGIN_ENTRYPOINT_NOTHROW; - - if (dwConnectionId == INVALID_CONNECTION_ID) - IfFailGo(E_INVALIDARG); - - // No connection exist at all - if (m_pConnectionNameHash == NULL) - IfFailGo(E_FAIL); - - { - CrstHolder ch(&m_lockConnectionNameTable); - ConnectionNameHashEntry *pEntry = NULL; - - if ((pEntry = m_pConnectionNameHash->FindConnection(dwConnectionId)) == NULL) - IfFailGo(E_INVALIDARG); - - // Note that the Release on CLRTask chould take a ThreadStoreLock. So we need to finish our - // business with ConnectionNameHash before hand and release our name hash lock - // - CLRTaskCount = pEntry->m_CLRTaskCount; - ppCLRTaskArray = pEntry->m_ppCLRTaskArray; - pEntry->m_ppCLRTaskArray = NULL; - pEntry->m_CLRTaskCount = 0; - m_pConnectionNameHash->DeleteConnection(dwConnectionId); - } - - if (CLRTaskCount != 0) - { - _ASSERTE(ppCLRTaskArray != NULL); - for (UINT i = 0; i < CLRTaskCount; i++) - { - ((Thread *)ppCLRTaskArray[i])->SetConnectionId(INVALID_CONNECTION_ID); - ppCLRTaskArray[i]->Release(); - } - delete [] ppCLRTaskArray; - } - - // send notification to debugger - if (CORDebuggerAttached()) - g_pDebugInterface->DestroyConnection(dwConnectionId); - -ErrExit: - END_ENTRYPOINT_NOTHROW; - - return hr; -} - -/* -* Call by host to set a set of tasks as a connection. -* -*/ -HRESULT CCLRDebugManager::SetConnectionTasks( - DWORD id, - DWORD dwCount, - ICLRTask **ppCLRTask) -{ - CONTRACTL - { - GC_TRIGGERS; - NOTHROW; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - ICLRTask **ppCLRTaskArrayNew = NULL; - UINT CLRTaskCountPrevious = 0; - ICLRTask **ppCLRTaskArrayPrevious = NULL; - - BEGIN_ENTRYPOINT_NOTHROW; - - DWORD index; - Thread *pThread; - ConnectionNameHashEntry *pEntry = NULL; - - if (id == INVALID_CONNECTION_ID || dwCount == 0 || ppCLRTask == NULL) - IfFailGo(E_INVALIDARG); - - { - CrstHolder ch(&m_lockConnectionNameTable); - - // check the BeginConnectin has been called. - if (m_pConnectionNameHash == NULL) - // No connection exist - IfFailGo(E_INVALIDARG); - // Host forget to call BeginConnection before calling SetConnectionTask! - if ((pEntry = m_pConnectionNameHash->FindConnection(id)) == NULL) - IfFailGo(E_INVALIDARG); - - for (index = 0; index < dwCount; index++) - { - // Check on input parameter - pThread = (Thread *) ppCLRTask[index]; - if (pThread == NULL) - { - // _ASSERTE(!"Host passed in NULL ICLRTask pointer"); - IfFailGo(E_INVALIDARG); - } - - // Check for Finalizer thread - if (GCHeapUtilities::IsGCHeapInitialized() && (pThread == FinalizerThread::GetFinalizerThread())) - { - // _ASSERTE(!"Host should not try to schedule user code on our Finalizer Thread"); - IfFailGo(E_INVALIDARG); - - } - } - - ppCLRTaskArrayNew = new (nothrow) ICLRTask*[dwCount]; - IfNullGo(ppCLRTaskArrayNew); - - CLRTaskCountPrevious = pEntry->m_CLRTaskCount; - ppCLRTaskArrayPrevious = pEntry->m_ppCLRTaskArray; - pEntry->m_ppCLRTaskArray = NULL; - pEntry->m_CLRTaskCount = 0; - - if (CLRTaskCountPrevious != 0) - { - // Clear the old connection set - _ASSERTE(ppCLRTaskArrayPrevious != NULL); - for (UINT i = 0; i < CLRTaskCountPrevious; i++) - ((Thread *)ppCLRTaskArrayPrevious[i])->SetConnectionId(INVALID_CONNECTION_ID); - } - - // now remember the new set - pEntry->m_ppCLRTaskArray = ppCLRTaskArrayNew; - - for (index = 0; index < dwCount; index++) - { - pThread = (Thread *) ppCLRTask[index]; - pThread->SetConnectionId( id ); - pEntry->m_ppCLRTaskArray[index] = ppCLRTask[index]; - } - pEntry->m_CLRTaskCount = dwCount; - - // AddRef and Release on Thread object can call ThreadStoreLock. So we will release our - // lock first of all. - } - - // Does the addref on the new set - for (index = 0; index < dwCount; index++) - ppCLRTaskArrayNew[index]->AddRef(); - - // Does the release on the old set - if (CLRTaskCountPrevious != 0) - { - _ASSERTE(ppCLRTaskArrayPrevious != NULL); - for (UINT i = 0; i < CLRTaskCountPrevious; i++) - ppCLRTaskArrayPrevious[i]->Release(); - delete ppCLRTaskArrayPrevious; - } - - // send notification to debugger - if (CORDebuggerAttached()) - { - g_pDebugInterface->ChangeConnection(id); - } - -ErrExit: - END_ENTRYPOINT_NOTHROW; - return hr; -} - -HRESULT CCLRDebugManager::SetDacl(PACL pacl) -{ - LIMITED_METHOD_CONTRACT; - STATIC_CONTRACT_ENTRY_POINT; - HRESULT hr; - - BEGIN_ENTRYPOINT_NOTHROW; - - hr = E_NOTIMPL; - - END_ENTRYPOINT_NOTHROW; - return hr; -} // SetDACL - - -HRESULT CCLRDebugManager::GetDacl(PACL *pacl) -{ - LIMITED_METHOD_CONTRACT; - STATIC_CONTRACT_ENTRY_POINT; - HRESULT hr; - - BEGIN_ENTRYPOINT_NOTHROW; - - hr = E_NOTIMPL; - - END_ENTRYPOINT_NOTHROW; - return hr; -} // SetDACL - -#endif // FEATURE_INCLUDE_ALL_INTERFACES - -#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE) +#if defined(FEATURE_WINDOWSPHONE) HRESULT CCLRErrorReportingManager::QueryInterface(REFIID riid, void** ppUnk) { @@ -6874,7 +2710,7 @@ CCLRErrorReportingManager::~CCLRErrorReportingManager() #endif } -#endif // defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE) +#endif // defined(FEATURE_WINDOWSPHONE) #ifdef FEATURE_IPCMAN @@ -7060,7 +2896,6 @@ HRESULT CCLRSecurityAttributeManager::GetDACL(PACL *ppacl) BOOL bDaclPresent; BOOL bDaclDefault; - LeaveRuntimeHolder holder((size_t)(::GetSecurityDescriptorDacl)); ::GetSecurityDescriptorDacl(pSA->lpSecurityDescriptor, &bDaclPresent, &pDefaultACL, &bDaclDefault); } EX_CATCH @@ -7213,21 +3048,6 @@ void GetProcessMemoryLoad(LPMEMORYSTATUSEX pMSEX) BOOL fRet = GlobalMemoryStatusEx(pMSEX); _ASSERTE (fRet); -#ifdef FEATURE_INCLUDE_ALL_INTERFACES - // CoreCLR cannot be memory hosted - if (CLRMemoryHosted()) - { - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - DWORD memoryLoad; - SIZE_T availableBytes; - HRESULT hr = CorHost2::GetHostMemoryManager()->GetMemoryLoad(&memoryLoad, &availableBytes); - if (hr == S_OK) { - pMSEX->dwMemoryLoad = memoryLoad; - pMSEX->ullAvailPhys = availableBytes; - } - END_SO_TOLERANT_CODE_CALLING_HOST; - } -#endif // FEATURE_INCLUDE_ALL_INTERFACES // If the machine has more RAM than virtual address limit, let us cap it. // Our GC can never use more than virtual address limit. @@ -7322,9 +3142,6 @@ struct ClrTlsInfo #define DataToClrTlsInfo(a) (a)?(ClrTlsInfo*)((BYTE*)a - offsetof(ClrTlsInfo, data)):NULL -#if !defined(FEATURE_CORECLR) -#define HAS_FLS_SUPPORT 1 -#endif #ifdef HAS_FLS_SUPPORT @@ -7415,84 +3232,6 @@ BOOL CExecutionEngine::SetTlsData (void** ppTlsInfo) #endif // FEATURE_IMPLICIT_TLS -static VolatilePtr<ClrTlsInfo> g_pDetachedTlsInfo; - -BOOL CExecutionEngine::HasDetachedTlsInfo() -{ - LIMITED_METHOD_CONTRACT; - - return g_pDetachedTlsInfo.Load() != NULL; -} - -void CExecutionEngine::CleanupDetachedTlsInfo() -{ - WRAPPER_NO_CONTRACT; - - if (g_pDetachedTlsInfo.Load() == NULL) - { - return; - } - ClrTlsInfo *head = FastInterlockExchangePointer(g_pDetachedTlsInfo.GetPointer(), NULL); - - while (head) - { - ClrTlsInfo *node = head; - head = head->next; - DeleteTLS(node->data); - } -} - -void CExecutionEngine::DetachTlsInfo(void **pTlsData) -{ - LIMITED_METHOD_CONTRACT; - - if (pTlsData == NULL) - { - return; - } - - if (CExecutionEngine::GetTlsData() == pTlsData) - { - CExecutionEngine::SetTlsData(0); - } - -#ifdef HAS_FLS_SUPPORT - if (fHasFlsSupport && pFlsGetValue(FlsIndex) == pTlsData) - { - pFlsSetValue(FlsIndex, NULL); - } -#endif - - ClrTlsInfo *pTlsInfo = DataToClrTlsInfo(pTlsData); - // PREFIX_ASSUME needs TLS. If we use it here, we may do memory allocation. -#if defined(_PREFAST_) || defined(_PREFIX_) - if (pTlsInfo == NULL) __UNREACHABLE(); -#else - _ASSERTE(pTlsInfo != NULL); -#endif // _PREFAST_ || _PREFIX_ - - if (pTlsInfo->data[TlsIdx_StressLog]) - { -#ifdef STRESS_LOG - CantAllocHolder caHolder; - StressLog::ThreadDetach ((ThreadStressLog *)pTlsInfo->data[TlsIdx_StressLog]); - pTlsInfo->data[TlsIdx_StressLog] = NULL; -#else - _ASSERTE (!"Shouldn't have stress log!"); -#endif - } - - while (TRUE) - { - ClrTlsInfo *head = g_pDetachedTlsInfo.Load(); - pTlsInfo->next = head; - if (FastInterlockCompareExchangePointer(g_pDetachedTlsInfo.GetPointer(), pTlsInfo, head) == head) - { - return; - } - } -} - //--------------------------------------------------------------------------------------- // // Returns the current logical thread's data block (ClrTlsInfo::data). @@ -7646,7 +3385,7 @@ void **CExecutionEngine::CheckThreadState(DWORD slot, BOOL force) // If we have a thread object or are on a non-fiber thread, we are safe for fiber switching. if (!fHasFlsSupport || GetThread() || - ((g_fEEStarted || g_fEEInit) && !CLRTaskHosted()) || + (g_fEEStarted || g_fEEInit) || (((size_t)pTlsInfo->data[TlsIdx_ThreadType]) & (ThreadType_GC | ThreadType_Gate | ThreadType_Timer | ThreadType_DbgHelper))) { #ifdef _DEBUG @@ -8187,7 +3926,6 @@ DWORD STDMETHODCALLTYPE CExecutionEngine::WaitForSingleObject(HANDLE handle, { STATIC_CONTRACT_WRAPPER; STATIC_CONTRACT_SO_TOLERANT; - LeaveRuntimeHolder holder((size_t)(::WaitForSingleObject)); return ::WaitForSingleObject(handle,dwMilliseconds); } @@ -8431,11 +4169,11 @@ SIZE_T STDMETHODCALLTYPE CExecutionEngine::ClrVirtualQuery(LPCVOID lpAddress, } #define ClrVirtualQuery EEVirtualQuery -#if defined(_DEBUG) && defined(FEATURE_CORECLR) && !defined(FEATURE_PAL) +#if defined(_DEBUG) && !defined(FEATURE_PAL) static VolatilePtr<BYTE> s_pStartOfUEFSection = NULL; static VolatilePtr<BYTE> s_pEndOfUEFSectionBoundary = NULL; static Volatile<DWORD> s_dwProtection = 0; -#endif // _DEBUG && FEATURE_CORECLR && !FEATURE_PAL +#endif // _DEBUG && !FEATURE_PAL #undef ClrVirtualProtect @@ -8481,7 +4219,7 @@ BOOL STDMETHODCALLTYPE CExecutionEngine::ClrVirtualProtect(LPVOID lpAddress, // // We assert if either of the two conditions above are true. -#if defined(_DEBUG) && defined(FEATURE_CORECLR) && !defined(FEATURE_PAL) +#if defined(_DEBUG) && !defined(FEATURE_PAL) // We do this check in debug/checked builds only // Do we have the UEF details? @@ -8551,7 +4289,7 @@ BOOL STDMETHODCALLTYPE CExecutionEngine::ClrVirtualProtect(LPVOID lpAddress, "Do not virtual protect the section in which UEF lives!"); } } -#endif // _DEBUG && FEATURE_CORECLR && !FEATURE_PAL +#endif // _DEBUG && !FEATURE_PAL return EEVirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect); } @@ -8655,14 +4393,11 @@ void CExecutionEngine::GetLastThrownObjectExceptionFromThread(void **ppvExceptio } // HRESULT CExecutionEngine::GetLastThrownObjectExceptionFromThread() -#ifdef FEATURE_VERSIONING LocaleID RuntimeGetFileSystemLocale() { return PEImage::GetFileSystemLocale(); }; -#endif -#ifdef FEATURE_CORECLR HRESULT CorHost2::DllGetActivationFactory(DWORD appDomainID, LPCWSTR wszTypeName, IActivationFactory ** factory) { #ifdef FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION @@ -8692,7 +4427,6 @@ HRESULT CorHost2::DllGetActivationFactory(DWORD appDomainID, LPCWSTR wszTypeName return E_NOTIMPL; #endif } -#endif #ifdef FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION @@ -8717,16 +4451,6 @@ HRESULT STDMETHODCALLTYPE DllGetActivationFactoryImpl(LPCWSTR wszAssemblyName, AppDomain* pDomain = SystemDomain::System()->DefaultDomain(); _ASSERTE(pDomain); -#ifndef FEATURE_CORECLR // coreclr uses winrt binder which does not allow redirects - { - BaseDomain::LockHolder lh(pDomain); - if (!pDomain->HasLoadContextHostBinder()) - { - // don't allow redirects - SystemDomain::InitializeDefaultDomain(FALSE); - } - } -#endif BEGIN_EXTERNAL_ENTRYPOINT(&hr); { @@ -8741,16 +4465,6 @@ HRESULT STDMETHODCALLTYPE DllGetActivationFactoryImpl(LPCWSTR wszAssemblyName, } gc; memset(&gc, 0, sizeof(gc)); -#if defined(FEATURE_MULTICOREJIT) && defined(FEATURE_APPX_BINDER) - // For Appx, multicore JIT is only needed when root assembly does not have NI image - // When it has NI image, we can't generate profile, and do not need to playback profile - if (AppX::IsAppXProcess() && ! typeHandle.IsZapped()) - { - GCX_PREEMP(); - - pDomain->GetMulticoreJitManager().AutoStartProfileAppx(pDomain); - } -#endif IActivationFactory* activationFactory; GCPROTECT_BEGIN(gc); @@ -8781,64 +4495,6 @@ HRESULT STDMETHODCALLTYPE DllGetActivationFactoryImpl(LPCWSTR wszAssemblyName, #endif // !FEATURE_COMINTEROP_MANAGED_ACTIVATION -#ifdef FEATURE_COMINTEROP_WINRT_DESKTOP_HOST - -HRESULT STDMETHODCALLTYPE GetClassActivatorForApplicationImpl(HSTRING appPath, IWinRTClassActivator** ppActivator) -{ - CONTRACTL - { - DISABLED(NOTHROW); - GC_TRIGGERS; - MODE_ANY; - ENTRY_POINT; - } - CONTRACTL_END; - - HRESULT hr = S_OK; - - BEGIN_ENTRYPOINT_NOTHROW; - BEGIN_EXTERNAL_ENTRYPOINT(&hr); - { - if (GetAppDomain()->GetWinRtBinder()->SetLocalWinMDPath(appPath)) - { - GCX_COOP(); - - struct - { - STRINGREF appbase; - } gc; - ZeroMemory(&gc, sizeof(gc)); - GCPROTECT_BEGIN(gc); - - UINT32 appPathLength = 0; - PCWSTR wszAppPath = WindowsGetStringRawBuffer(appPath, &appPathLength); - - gc.appbase = StringObject::NewString(wszAppPath, appPathLength); - - MethodDescCallSite getClassActivator(METHOD__WINDOWSRUNTIMEMARSHAL__GET_CLASS_ACTIVATOR_FOR_APPLICATION); - - ARG_SLOT args[] = - { - ObjToArgSlot(gc.appbase) - }; - - IWinRTClassActivator* pActivator = reinterpret_cast<IWinRTClassActivator *>(getClassActivator.Call_RetLPVOID(args)); - *ppActivator = pActivator; - - GCPROTECT_END(); - } - else - { - hr = CO_E_BAD_PATH; - } - } - END_EXTERNAL_ENTRYPOINT; - END_ENTRYPOINT_NOTHROW; - - return hr; -} - -#endif // FEATURE_COMINTEROP_WINRT_DESKTOP_HOST #endif // !DACCESS_COMPILE |