PTR_IUnknown pUnk = dac_cast<PTR_IUnknown>(*dac_cast<PTR_TADDR>(pUnkStackSlot));
ComCallWrapper * pCCW = ComCallWrapper::GetWrapperFromIP(pUnk);
- if (!pCCW->NeedToSwitchDomains(pAppDomain->GetId()))
- {
- ComCallMethodDesc * pCMD = NULL;
- pCMD = dac_cast<PTR_ComCallMethodDesc>(pCOMFrame->ComMethodFrame::GetDatum());
- pMD = pCMD->GetInterfaceMethodDesc();
- }
+ ComCallMethodDesc * pCMD = NULL;
+ pCMD = dac_cast<PTR_ComCallMethodDesc>(pCOMFrame->ComMethodFrame::GetDatum());
+ pMD = pCMD->GetInterfaceMethodDesc();
}
}
EX_END_CATCH_ALLOW_DATATARGET_MISSING_MEMORY
// Write out the Thread instance
DacEnumHostDPtrMem(pThread);
- // Write out the context pointed by the thread
- DacEnumHostDPtrMem(pThread->GetContext());
-
// @TODO
// write TEB pointed by the thread
// DacEnumHostDPtrMem(pThread->GetTEB());
threadData->fiberData = NULL;
threadData->pFrame = PTR_CDADDR(thread->m_pFrame);
- threadData->context = PTR_CDADDR(thread->m_Context);
+ threadData->context = PTR_CDADDR(thread->m_pDomain);
threadData->domain = PTR_CDADDR(thread->m_pDomain);
threadData->lockCount = thread->m_dwLockCount;
#ifndef FEATURE_PAL
SOSDacEnter();
- Context* context = PTR_Context(TO_TADDR(contextAddr));
- *domain = HOST_CDADDR(context->GetDomain());
+ *domain = contextAddr; // Context is same as the AppDomain in CoreCLR
SOSDacLeave();
return hr;
#include "eeconfig.h" // This is here even for retail & free builds...
#include "../../dlls/mscorrc/resource.h"
-
-#include "context.h"
#include "vars.hpp"
#include <limits.h>
#include "ilformatter.h"
#include "eeconfig.h" // This is here even for retail & free builds...
#include "../../dlls/mscorrc/resource.h"
-
-#include "context.h"
#include "vars.hpp"
#include "threads.h"
#include "appdomain.inl"
set(VM_SOURCES_DAC
${VM_SOURCES_DAC_AND_WKS_COMMON}
- contexts.cpp
threaddebugblockinginfo.cpp
)
// to allow stub caches to use the memory pool. Do not
// initialze it here!
-#ifndef CROSSGEN_COMPILE
-#ifdef _DEBUG
- Context *curCtx = GetCurrentContext();
-#endif
- _ASSERTE(curCtx);
- _ASSERTE(curCtx->GetDomain() != NULL);
-#endif
-
#ifdef FEATURE_PREJIT
if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_ZapDisable) != 0)
g_fAllowNativeImages = false;
m_pRootAssembly = NULL;
m_dwFlags = 0;
- m_pDefaultContext = NULL;
#ifdef FEATURE_COMINTEROP
m_pRCWCache = NULL;
m_pRCWRefCache = NULL;
SetStage(STAGE_READYFORMANAGEDCODE);
#ifndef CROSSGEN_COMPILE
- m_pDefaultContext = new Context(this);
-
m_ExposedObject = CreateHandle(NULL);
COUNTER_ONLY(GetPerfCounters().m_Loading.cAppDomains++);
_ASSERTE(m_dwThreadEnterCount == 0 || IsDefaultDomain());
- delete m_pDefaultContext;
- m_pDefaultContext = NULL;
-
#ifdef FEATURE_COMINTEROP
if (m_pRCWCache)
{
class AppDomainEnum;
class AssemblySink;
class EEMarshalingData;
-class Context;
class GlobalStringLiteralMap;
class StringLiteralMap;
class MngStdInterfacesInfo;
#endif
DomainAssembly* FindDomainAssembly(Assembly*);
- void EnterContext(Thread* pThread, Context* pCtx,ContextTransitionFrame *pFrame);
//-----------------------------------------------------------------------------------------------------------------
// Convenience wrapper for ::GetAppDomain to provide better encapsulation.
return m_dwThreadEnterCount==1 || m_dwThreadsStillInAppDomain ==1;
}
- Context *GetDefaultContext()
- {
- LIMITED_METHOD_CONTRACT;
- return m_pDefaultContext;
- }
-
BOOL CanLoadCode()
{
LIMITED_METHOD_CONTRACT;
Volatile<Stage> m_Stage;
- // The default context for this domain
- Context *m_pDefaultContext;
-
ArrayList m_failedAssemblies;
#ifdef _DEBUG
#include "appdomain.hpp"
-inline void AppDomain::EnterContext(Thread* pThread, Context* pCtx,ContextTransitionFrame *pFrame)
-{
- CONTRACTL
- {
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pThread));
- PRECONDITION(CheckPointer(pCtx));
- PRECONDITION(CheckPointer(pFrame));
- PRECONDITION(pCtx->GetDomain()==this);
- }
- CONTRACTL_END;
- pThread->EnterContextRestricted(pCtx,pFrame);
-};
-
inline DomainAssembly* AppDomain::FindDomainAssembly(Assembly* assembly)
{
CONTRACTL
pComMT->CheckParentComVisibility(FALSE);
}
- ENTER_DOMAIN_ID_PREDICATED(pWrap->GetDomainID(), !!pWrap->NeedToSwitchDomains(pThread))
{
OBJECTREF pADThrowable = NULL;
GCPROTECT_END();
}
}
- END_DOMAIN_TRANSITION;
}
EX_CATCH
{
AppDomain *pDomain = pCurrentThread->GetDomain();
m_adid = pDomain->GetId();
- m_pContext = pCurrentThread->GetContext();
{
GCX_COOP_THREAD_EXISTS(pCurrentThread);
WeakReferenceResolveCallbackArgs args = { this, pThread, riid, ppvObject, &hr };
- //
- // Transition to the right domain
- // WeakReference is bound to the domain where this WeakReference is created, so we must
- // transition to the domain of WeakReference, not the domain of the CCW, as they might be different
- // if the CCW is agile.
- //
- if (pThread->GetDomain()->GetId() == m_adid)
- {
- Resolve_Callback(&args);
- }
- else
- {
- GCX_COOP_THREAD_EXISTS(pThread);
-
- pThread->DoContextCallBack(
- m_adid,
- m_pContext,
- (Context::ADCallBackFcnType)Resolve_Callback_SwitchToPreemp,
- (LPVOID)&args);
- }
-
+ Resolve_Callback(&args);
}
END_EXTERNAL_ENTRYPOINT;
// do this for each of the CCWs
m_pWrap->Neuter();
}
-
- // NULL the context, we shall only use m_dwDomainId from this point on
- m_pContext = NULL;
StackSString ssMessage;
ComCallWrapper *pWrap = m_pWrap;
// and the main ComCallWrapper if the interface needs it
//--------------------------------------------------------------------------
void SimpleComCallWrapper::InitNew(OBJECTREF oref, ComCallWrapperCache *pWrapperCache, ComCallWrapper* pWrap,
- ComCallWrapper *pClassWrap, Context *pContext, SyncBlock *pSyncBlock,
+ ComCallWrapper *pClassWrap, SyncBlock *pSyncBlock,
ComCallWrapperTemplate* pTemplate)
{
CONTRACTL
PRECONDITION(oref != NULL);
PRECONDITION(CheckPointer(pWrap));
PRECONDITION(CheckPointer(pWrapperCache, NULL_OK));
- PRECONDITION(CheckPointer(pContext));
PRECONDITION(CheckPointer(pSyncBlock, NULL_OK));
PRECONDITION(CheckPointer(pTemplate));
PRECONDITION(m_pSyncBlock == NULL);
m_pOuter = NULL;
m_pSyncBlock = pSyncBlock;
- m_pContext = pContext;
- m_dwDomainId = pContext->GetDomain()->GetId();
-
- //@TODO: CTS, when we transition into the correct context before creating a wrapper
- // then uncomment the next line
- //_ASSERTE(pContext == GetCurrentContext());
+ m_dwDomainId = GetAppDomain()->GetId();
if (pMT->IsComObjectType())
m_flags |= enum_IsExtendsCom;
pServer = *ppObj;
- Context *pContext = GetAppDomain()->GetDefaultContext();
-
// Force Refine the object if it is a transparent proxy
RefineProxy(pServer);
// if the object is agile in non-checked, so we trust that our checking works and when we
// attempt to hand this out to another domain then we will assume that the object is truly
// agile and will convert the handle to a global handle.
- oh = pContext->GetDomain()->CreateRefcountedHandle(NULL);
+ oh = GetAppDomain()->CreateRefcountedHandle(NULL);
_ASSERTE(oh);
}
else
NewHolder<SimpleComCallWrapper> pSimpleWrap = SimpleComCallWrapper::CreateSimpleWrapper();
- pSimpleWrap->InitNew(pServer, pWrapperCache, pNewCCW, pClassCCW, pContext, pSyncBlock, pTemplate);
+ pSimpleWrap->InitNew(pServer, pWrapperCache, pNewCCW, pClassCCW, pSyncBlock, pTemplate);
InitSimpleWrapper(pNewCCW, pSimpleWrap);
}
}
-VOID InvokeICustomQueryInterfaceGetInterface_AppDomainTransition(LPVOID ptr, ADID targetADID, Context *pTargetContext)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(ptr));
- }
- CONTRACTL_END;
- Thread *pThread = GetThread();
- GCX_COOP_THREAD_EXISTS(pThread);
- pThread->DoContextCallBack(
- targetADID,
- pTargetContext,
- (Context::ADCallBackFcnType)InvokeICustomQueryInterfaceGetInterface_CallBack,
- ptr);
-}
-
// Returns a covariant supertype of pMT with the given IID or NULL if not found.
// static
MethodTable *ComCallWrapper::FindCovariantSubtype(MethodTable *pMT, REFIID riid)
InvokeICustomQueryInterfaceGetInterfaceArgs args = {pWrap, &guid, ppUnkOut, &retVal};
- ADID targetADID;
- Context *pTargetContext;
- if (pWrap->NeedToSwitchDomains(GetThread(), &targetADID, &pTargetContext))
- InvokeICustomQueryInterfaceGetInterface_AppDomainTransition(&args, targetADID, pTargetContext);
- else
- InvokeICustomQueryInterfaceGetInterface_CallBack(&args);
+ InvokeICustomQueryInterfaceGetInterface_CallBack(&args);
+
// return if user already handle the QI
if (retVal == Handled)
return true;
public:
ADID GetDomainID();
- // The first overload respects the is-agile flag and context, the other two respect the flag but
- // ignore the context (this is mostly for back compat reasons, new code should call the first overload).
- BOOL NeedToSwitchDomains(Thread *pThread, ADID *pTargetADID, Context **ppTargetContext);
- BOOL NeedToSwitchDomains(Thread *pThread);
- BOOL NeedToSwitchDomains(ADID appdomainID);
-
VOID ResetHandleStrength();
VOID MarkHandleWeak();
{
private:
ADID m_adid; // AppDomain ID of where this weak reference is created
- Context *m_pContext; // Saved context
OBJECTHANDLE m_ppObject; // Short weak global handle points back to the object,
// created in domain ID = m_adid
// Init pointer to the vtable of the interface
// and the main ComCallWrapper if the interface needs it
void InitNew(OBJECTREF oref, ComCallWrapperCache *pWrapperCache, ComCallWrapper* pWrap,
- ComCallWrapper *pClassWrap, Context* pContext, SyncBlock* pSyncBlock,
+ ComCallWrapper *pClassWrap, SyncBlock* pSyncBlock,
ComCallWrapperTemplate* pTemplate);
// used by reconnect wrapper to new object
return m_dwDomainId;
}
- inline BOOL NeedToSwitchDomains(Thread *pThread, ADID *pTargetADID, Context **ppTargetContext)
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return FALSE;
- }
- inline BOOL NeedToSwitchDomains(ADID appdomainID)
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return FALSE;
- }
-
// is the object aggregated by a COM component
BOOL IsAggregated()
{
PTR_ComCallWrapper m_pWrap; // the first ComCallWrapper associated with this SimpleComCallWrapper
PTR_ComCallWrapper m_pClassWrap; // the first ComCallWrapper associated with the class (only if m_pMT is an interface)
MethodTable* m_pMT;
- Context* m_pContext;
ComCallWrapperCache* m_pWrapperCache;
PTR_ComCallWrapperTemplate m_pTemplate;
RETURN pWrap;
}
-#ifndef CROSSGEN_COMPILE
-
-inline BOOL ComCallWrapper::NeedToSwitchDomains(Thread *pThread, ADID *pTargetADID, Context **ppTargetContext)
-{
- WRAPPER_NO_CONTRACT;
-
- return GetSimpleWrapper()->NeedToSwitchDomains(pThread, pTargetADID, ppTargetContext);
-}
-
-inline BOOL ComCallWrapper::NeedToSwitchDomains(Thread *pThread)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- return NeedToSwitchDomains(pThread->GetDomain()->GetId());
-}
-
-
-inline BOOL ComCallWrapper::NeedToSwitchDomains(ADID appdomainID)
-{
- WRAPPER_NO_CONTRACT;
-
- return GetSimpleWrapper()->NeedToSwitchDomains(appdomainID);
-}
-
-#endif // CROSSGEN_COMPILE
-
inline ADID ComCallWrapper::GetDomainID()
{
WRAPPER_NO_CONTRACT;
// Implementation of helper class used to expose connection points
//------------------------------------------------------------------------------------------
-void ConnectionPoint::Advise_Wrapper(LPVOID ptr)
-{
- WRAPPER_NO_CONTRACT;
-
- Advise_Args *pArgs = (Advise_Args *)ptr;
- pArgs->pThis->AdviseWorker(pArgs->pUnk, pArgs->pdwCookie);
-}
-
-void ConnectionPoint::Unadvise_Wrapper(LPVOID ptr)
-{
- WRAPPER_NO_CONTRACT;
-
- Unadvise_Args *pArgs = (Unadvise_Args *)ptr;
- pArgs->pThis->UnadviseWorker(pArgs->dwCookie);
-}
-
-void ConnectionPoint::GetConnectionPointContainer_Wrapper(LPVOID ptr)
-{
- WRAPPER_NO_CONTRACT;
-
- GetConnectionPointContainer_Args *pArgs = (GetConnectionPointContainer_Args *)ptr;
- *pArgs->ppCPC = pArgs->pThis->GetConnectionPointContainerWorker();
-}
-
ConnectionPoint::ConnectionPoint(ComCallWrapper *pWrap, MethodTable *pEventMT)
: m_pOwnerWrap(pWrap)
, m_pTCEProviderMT(pWrap->GetSimpleWrapper()->GetMethodTable())
BEGIN_EXTERNAL_ENTRYPOINT(&hr)
{
GCX_COOP_THREAD_EXISTS(GET_THREAD());
- Thread *pThread = GET_THREAD();
- ADID targetADID;
- Context *pTargetContext;
- if (m_pOwnerWrap->NeedToSwitchDomains(pThread, &targetADID, &pTargetContext))
- {
- GetConnectionPointContainer_Args args = {this, ppCPC};
- pThread->DoContextCallBack(targetADID, pTargetContext, GetConnectionPointContainer_Wrapper, &args);
- }
- else
- {
- *ppCPC = GetConnectionPointContainerWorker();
- }
+ *ppCPC = GetConnectionPointContainerWorker();
}
END_EXTERNAL_ENTRYPOINT;
BEGIN_EXTERNAL_ENTRYPOINT(&hr)
{
GCX_COOP_THREAD_EXISTS(GET_THREAD());
- Thread *pThread = GET_THREAD();
- ADID targetADID;
- Context *pTargetContext;
- if (m_pOwnerWrap->NeedToSwitchDomains(pThread, &targetADID, &pTargetContext))
- {
- Advise_Args args = {this, pUnk, pdwCookie};
- pThread->DoContextCallBack(targetADID, pTargetContext, Advise_Wrapper, &args);
- }
- else
- {
- AdviseWorker(pUnk, pdwCookie);
- }
+ AdviseWorker(pUnk, pdwCookie);
}
END_EXTERNAL_ENTRYPOINT;
BEGIN_EXTERNAL_ENTRYPOINT(&hr)
{
GCX_COOP_THREAD_EXISTS(GET_THREAD());
- Thread *pThread = GET_THREAD();
- ADID targetADID;
- Context *pTargetContext;
- if (m_pOwnerWrap->NeedToSwitchDomains(pThread, &targetADID, &pTargetContext))
- {
- Unadvise_Args args = {this, dwCookie};
- pThread->DoContextCallBack(targetADID, pTargetContext, Unadvise_Wrapper, &args);
- }
- else
- {
- UnadviseWorker(dwCookie);
- }
+ UnadviseWorker(dwCookie);
}
END_EXTERNAL_ENTRYPOINT;
void UnadviseWorker( DWORD dwCookie );
IConnectionPointContainer *GetConnectionPointContainerWorker();
- // AD callback wrappers.
- static void GetConnectionPointContainer_Wrapper(LPVOID ptr);
- static void Advise_Wrapper(LPVOID ptr);
- static void Unadvise_Wrapper(LPVOID ptr);
-
// Helper methods.
void SetupEventMethods();
MethodDesc *FindProviderMethodDesc( MethodDesc *pEventMethodDesc, EnumEventMethods MethodType );
END_SO_TOLERANT_CODE;
}
-#ifdef _TARGET_X86_
-// On x86, we do not want the non-AD-transition path to push an extra FS:0 handler just to
-// pop off the ComMethodFrame. On non-x86, we have a personality routine that does this
-// (ReverseComUnwindFrameChainHandler), but on x86 we will latch onto the typical CPFH by
-// pushing COMPlusFrameHandlerRevCom as the FS:0 handler instead of COMPlusFrameHandler.
-// COMPlusFrameHandlerRevCom will look at the Frame chain from the current Frame up to
-// the ComMethodFrame and, if it finds a ContextTransitionFrame, it will do nothing.
-// Otherwise, it will unwind the Frame chain up to the ComMethodFrame. So here we latch
-// onto the AD transition rethrow as the point at which to unwind the Frame chain up to
-// the ComMethodFrame.
-#define REVERSE_COM_RETHROW_HOOK(pFrame) { ComMethodFrame::DoSecondPassHandlerCleanup(pFrame); }
-#else
-#define REVERSE_COM_RETHROW_HOOK(pFrame) NULL
-#endif // _TARGET_X86_
-
-NOINLINE
-void COMToCLRWorkerBodyWithADTransition(
- Thread * pThread,
- ComMethodFrame * pFrame,
- ComCallWrapper * pWrap,
- UINT64 * pRetValOut)
-{
- CONTRACTL
- {
- NOTHROW; // Although CSE can be thrown
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- BOOL fEnteredDomain = FALSE;
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(pThread, { *pRetValOut = COR_E_STACKOVERFLOW; return; } );
- EX_TRY
- {
- ADID pTgtDomain = pWrap->GetDomainID();
- ENTER_DOMAIN_ID(pTgtDomain)
- {
- fEnteredDomain = TRUE;
- COMToCLRWorkerBody_SOIntolerant(pThread, pFrame, pWrap, pRetValOut);
- }
- END_DOMAIN_TRANSITION;
- }
- EX_CATCH
- {
- *pRetValOut = SetupErrorInfo(GET_THROWABLE(), pFrame->GetComCallMethodDesc());
- }
- EX_END_CATCH(
- RethrowCorruptingExceptionsExAndHookRethrow(
- // If it was thrown at us from the IL stub (which will evaluate the CE policy), then we must
- // rethrow it here. But we should swallow exceptions generated by our domain transition.
- fEnteredDomain,
- REVERSE_COM_RETHROW_HOOK(pThread->GetFrame())
- ));
-
- END_SO_INTOLERANT_CODE;
-}
-
-
//------------------------------------------------------------------
// UINT64 __stdcall COMToCLRWorker(Thread *pThread,
// ComMethodFrame* pFrame)
// Obtain the managed 'this' for the call
ComCallWrapper *pWrap = ComCallWrapper::GetWrapperFromIP(pUnk);
- _ASSERTE(pWrap != NULL);
- if (pWrap->NeedToSwitchDomains(pThread))
- {
- COMToCLRWorkerBodyWithADTransition(pThread, pFrame, pWrap, &retVal);
- }
- else
- {
- // This is the common case that needs to be fast: we are in the right domain and
- // all we have to do is marshal the parameters and deliver the call.
- COMToCLRWorkerBody(pThread, pFrame, pWrap, &retVal);
- }
+ COMToCLRWorkerBody(pThread, pFrame, pWrap, &retVal);
}
}
OBJECTREF pThrowable = NULL;
GCPROTECT_BEGIN(pThrowable);
{
- if (!pWrap->NeedToSwitchDomains(pThread))
+ EX_TRY
{
- // This is the common case that needs to be fast: we are in the right domain and
- // all we have to do is marshal the parameters and deliver the call. We still have to
- // set up an EX_TRY/EX_CATCH to transform any exceptions that were thrown into
- // HRESULTs.
- EX_TRY
- {
- FieldCallWorkerDebuggerWrapper(pThread, pFrame);
- }
- EX_CATCH
- {
- pThrowable = GET_THROWABLE();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- if (pThrowable != NULL)
- {
- // Transform the exception into an HRESULT. This also sets up
- // an IErrorInfo on the current thread for the exception.
- hrRetVal = SetupErrorInfo(pThrowable, pFrame->GetComCallMethodDesc());
- pThrowable = NULL;
- }
+ FieldCallWorkerDebuggerWrapper(pThread, pFrame);
}
- else
+ EX_CATCH
{
- ADID pTgtDomain = pWrap->GetDomainID();
- if (!pTgtDomain.m_dwId)
- {
- hrRetVal = COR_E_APPDOMAINUNLOADED;
- }
- else
- {
- // We need a try/catch around the code to enter the domain since entering
- // an AppDomain can throw an exception.
- EX_TRY
- {
- ENTER_DOMAIN_ID(pTgtDomain)
- {
- // Set up a new GC protection frame for any exceptions thrown inside the AppDomain. Do
- // this so we can be sure we don't leak an AppDomain-specific object outside the
- // lifetime of the AppDomain (which can happen if an AppDomain unload causes us to
- // unwind out via a ThreadAbortException).
- OBJECTREF pAppDomainThrowable = NULL;
- GCPROTECT_BEGIN(pAppDomainThrowable);
- {
- // We need a try/catch around the call to the worker since we need
- // to transform any exceptions into HRESULTs. We want to do this
- // inside the AppDomain of the CCW.
- EX_TRY
- {
- FieldCallWorkerDebuggerWrapper(pThread, pFrame);
- }
- EX_CATCH
- {
- pAppDomainThrowable = GET_THROWABLE();
- }
- EX_END_CATCH(RethrowTerminalExceptions);
-
- if (pAppDomainThrowable != NULL)
- {
- // Transform the exception into an HRESULT. This also sets up
- // an IErrorInfo on the current thread for the exception.
- hrRetVal = SetupErrorInfo(pAppDomainThrowable, pFrame->GetComCallMethodDesc());
- pAppDomainThrowable = NULL;
- }
- }
- GCPROTECT_END();
- }
- END_DOMAIN_TRANSITION;
- }
- EX_CATCH
- {
- // Transform the exception into an HRESULT. This also sets up
- // an IErrorInfo on the current thread for the exception.
- pThrowable = GET_THROWABLE();
- }
- EX_END_CATCH(SwallowAllExceptions);
+ pThrowable = GET_THROWABLE();
+ }
+ EX_END_CATCH(SwallowAllExceptions);
- if (pThrowable != NULL)
- {
- // Transform the exception into an HRESULT. This also sets up
- // an IErrorInfo on the current thread for the exception.
- hrRetVal = SetupErrorInfo(pThrowable, pFrame->GetComCallMethodDesc());
- pThrowable = NULL;
- }
- }
+ if (pThrowable != NULL)
+ {
+ // Transform the exception into an HRESULT. This also sets up
+ // an IErrorInfo on the current thread for the exception.
+ hrRetVal = SetupErrorInfo(pThrowable, pFrame->GetComCallMethodDesc());
}
}
DWORD res = (DWORD) -1;
- Context* targetContext;
- targetContext = pThread->GetContext();
- _ASSERTE(targetContext);
- Context* defaultContext;
- defaultContext = pThread->GetDomain()->GetDefaultContext();
- _ASSERTE(defaultContext);
SafeHandleHolder shh(&sh);
// Note that SafeHandle is a GC object, and RequestCallback and
// DoAppropriateWait work on an array of handles. Don't pass the address
// array.
HANDLE handles[1];
handles[0] = sh->GetHandle();
- _ASSERTE(exitContext == NULL || targetContext == defaultContext);
{
// Support for pause/resume (FXFREEZE)
while(true)
}
DWORD res = (DWORD) -1;
- Context* targetContext;
- targetContext = pThread->GetContext();
- _ASSERTE(targetContext);
- Context* defaultContext;
- defaultContext = pThread->GetDomain()->GetDefaultContext();
- _ASSERTE(defaultContext);
- _ASSERTE(exitContext == NULL || targetContext == defaultContext);
{
// Support for pause/resume (FXFREEZE)
while(true)
DWORD res = (DWORD) -1;
- Context* targetContext = pThread->GetContext();
- _ASSERTE(targetContext);
- Context* defaultContext = pThread->GetDomain()->GetDefaultContext();
- _ASSERTE(defaultContext);
-
-
SafeHandleHolder shhSignal(&shSignal);
SafeHandleHolder shhWait(&shWait);
// Don't pass the address of the handle field
HANDLE handles[2];
handles[0] = shSignal->GetHandle();
handles[1] = shWait->GetHandle();
- _ASSERTE(exitContext == NULL || targetContext == defaultContext);
{
res = pThread->DoSignalAndWait(handles,timeout,TRUE /*alertable*/);
}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-
-#ifndef _H_CONTEXT_
-#define _H_CONTEXT_
-
-#include "specialstatics.h"
-#include "fcall.h"
-
-#ifdef FEATURE_COMINTEROP
-class RCWCache;
-#endif // FEATURE_COMINTEROP
-
-typedef DPTR(class Context) PTR_Context;
-
-
-// there will be only the default context for each appdomain
-// and contexts will not be exposed to users (so there will be no managed Context class)
-
-class Context
-{
- PTR_AppDomain m_pDomain;
-
-public:
-#ifndef DACCESS_COMPILE
- Context(AppDomain *pDomain)
- {
- m_pDomain = pDomain;
- }
-#endif
-
- PTR_AppDomain GetDomain()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return m_pDomain;
- }
-
- typedef void (*ADCallBackFcnType)(LPVOID);
-
-#ifdef DACCESS_COMPILE
- void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
-#endif
-};
-
-
-#endif
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-// Contexts.CPP
-//
-
-//
-// Implementation for class Context
-//
-
-
-#include "common.h"
-
-
-#ifdef DACCESS_COMPILE
-
-void
-Context::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
-{
- SUPPORTS_DAC;
- DAC_ENUM_DTHIS();
-
- if (m_pDomain.IsValid())
- {
- m_pDomain->EnumMemoryRegions(flags, true);
- }
-}
-#endif // #ifdef DACCESS_COMPILE
#endif // FEATURE_CORRUPTING_EXCEPTIONS
-#ifndef DACCESS_COMPILE
-// When a managed thread starts in non-default domain, its callstack looks like below:
-//
-// <ManagedThreadBase_DispatchOuter>
-// <ManagedThreadBase_DispatchMiddle>
-// <ManagedThreadBase_DispatchInner>
-//
-// -- AD transition is here -- ==> Pushes ContextTransitionFrame and has EX_CATCH
-//
-// <ManagedThreadBase_DispatchOuter>
-// <ManagedThreadBase_DispatchMiddle>
-// <ManagedThreadBase_DispatchInner>
-//
-// In CoreCLR, all managed threads spawned will have a stack like this since they all
-// run in non-DefaultDomain. The upper three frames are in default domain and the lower
-// three are in the non-default domain in which the thread was created. Any exception
-// that is unhandled in non-default domain will be caught at AD transition boundary.
-// The transition boundary does the following tasks:
-//
-// 1) Catch any incoming unhandled exception from the non-default domain using EX_CATCH.
-// 2) Marshal the exception object to the return context (i.e. DefaultDomain)
-// 3) Return to the context of DefaultDomain and throw the marshalled exception object there.
-//
-// All this depends upon the EX_CATCH (which is based upon C++ exception handling) being
-// able to catch the exception.
-//
-// However, if a breakpoint exception ia raised and a debugger is not available to handle it,
-// C++'s catch(...) will not be able to catch it, even when compiled with /EHa. For the curious,
-// refer to "FindHandlerForForeignException" function's implementation in the CRT. One of the first
-// things it does is check for breakpoint exception and if it is, it will simply bail out of the
-// process of finding a handler. Thus, EX_CATCH will not be able to catch this exception and we
-// will not be able to transition to the previous AD context.
-//
-// Imagine a thread in non-default domain suffers breakpoint exception. Assuming it will go unhandled,
-// it will reach the OS, which will trigger an unwind. The execution of termination handlers in lower
-// three frames (above) is fine since they are in the same AD as the thread. But when termination
-// handlers in the upper three frames execute, its a case of bad mixup since the thread is in a different
-// AD context than what the frames are expected to be in.
-//
-// Hence, we need a mechanism to transition to the expected AppDomain in case of breakpoint exception.
-// This function supports this mechanism in a generic fashion, i.e., one can use it to transition to
-// any AppDomain, though only up the stack.
-
-BOOL ReturnToPreviousAppDomain()
-{
- STATIC_CONTRACT_GC_NOTRIGGER;
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_MODE_COOPERATIVE;
- STATIC_CONTRACT_SO_TOLERANT;
-
- Thread *pCurThread = GetThread();
- _ASSERTE(pCurThread != NULL);
-
- BOOL fTransitioned = FALSE;
-
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(pCurThread, return FALSE);
-
- // Get the thread's current domain
- AppDomain *pCurDomain = pCurThread->GetDomain();
- _ASSERTE(pCurDomain != NULL);
-
- // Lookup the ContextTransitionFrame for the transition into the current AppDomain.
- Frame *pCtxTransitionFrame = pCurThread->GetFirstTransitionInto(pCurDomain, NULL);
- if (pCtxTransitionFrame == NULL)
- {
- // Since we couldnt find the context transition frame, check if its the default domain.
- // If so, we will set fTransitioned to TRUE since there is no context transition frame
- // setup for the initial entry into the default domain. For all other transitions to it
- // from non-default domains, we will have a context transition frame. We will do a
- // debug-only check to assert this invariant.
- BOOL fIsDefDomain = pCurDomain->IsDefaultDomain();
-#ifdef _DEBUG
- if (fIsDefDomain)
- {
- // Start with the topmost frame and look for a CTX frame until we reach the top of the frame chain.
- // We better not find one since we couldnt find a transition frame to the DefaultDomain.
- Frame *pStartFrame = pCurThread->GetFrame();
- BOOL fFoundCTXFrame = FALSE;
- while ((pStartFrame != NULL) && (pStartFrame != (Frame *)FRAME_TOP))
- {
- if (pStartFrame->GetVTablePtr() == ContextTransitionFrame::GetMethodFrameVPtr())
- {
- fFoundCTXFrame = TRUE;
- break;
- }
-
- // Get the next frame in the chain
- pStartFrame = pStartFrame->PtrNextFrame();
- }
-
- _ASSERTE_MSG(!fFoundCTXFrame, "How come we didnt find the transition frame to DefDomain but found another CTX frame on the frame chain?");
- }
-#endif // _DEBUG
- fTransitioned = fIsDefDomain;
- LOG((LF_EH, LL_INFO100, "ReturnToPreviousAppDomain: Unable to find the transition into the current domain (IsDefaultDomain: %d).\n", fIsDefDomain));
-
- goto done;
- }
-
- // Confirm its the correct type of frame
- _ASSERTE_MSG(pCtxTransitionFrame->GetVTablePtr() == ContextTransitionFrame::GetMethodFrameVPtr(),
- "How come we didn't find context transition frame for this AD transition?");
-
- // Get the topmost Frame
- Frame *pCurFrame;
- pCurFrame = pCurThread->GetFrame();
-
- // <ASSUMPTION>
- //
- // The loop below assumes we are called during an exception unwind since it
- // unwinds the Frames and pops them off the thread.
- //
- // </ASSUMPTION>
- //
- // Clear all the frames until we are at the frame of our interest. If there was a
- // CTX frame between the topmost frame and the AD transition, then we should be able to
- // catch it here as well.
- while((pCurFrame != NULL) && (pCurFrame < pCtxTransitionFrame) &&
- (pCurFrame->GetVTablePtr() != ContextTransitionFrame::GetMethodFrameVPtr()))
- {
- // Invoke exception unwind and pop the frame off
- pCurFrame->ExceptionUnwind();
- pCurFrame->Pop();
- pCurFrame = pCurThread->GetFrame();
- }
-
- // Confirm that we are at the expected Frame.
- _ASSERTE_MSG(((pCurFrame != NULL) &&
- (pCurFrame->GetVTablePtr() == ContextTransitionFrame::GetMethodFrameVPtr()) &&
- (pCurFrame == pCtxTransitionFrame)),
- "How come we are not at the exact context transition frame?");
-
- // Log our context return
- LOG((LF_EH, LL_INFO100, "ReturnToPreviousAppDomain: Returning from AD %d to AD %d\n",
- GetAppDomain()->GetId().m_dwId, pCtxTransitionFrame->GetReturnDomain()->GetId().m_dwId));
-
- // Return to the previous AD context
- pCurThread->ReturnToContext((ContextTransitionFrame *)pCtxTransitionFrame);
-
-#ifdef _DEBUG
- // At this point, the context transition frame would have been popped off by
- // ReturnToContext above.
- pCurFrame = pCurThread->GetFrame();
- _ASSERTE_MSG(pCurFrame != pCtxTransitionFrame, "How come the CTX frame of AD transition is still on the frame chain?");
-#endif // _DEBUG
-
- // Set the flag that we transitioned correctly.
- fTransitioned = TRUE;
-
-done:;
- END_SO_INTOLERANT_CODE;
-
- return fTransitioned;
-}
-
-// This class defines a holder that can be used to return to previous AppDomain incase an exception
-// goes across an AD transition boundary without reverting the active context.
-//
-// Use this holder *after* you have transitioned to the target AD.
-void ReturnToPreviousAppDomainHolder::Init()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- m_fShouldReturnToPreviousAppDomain = TRUE;
- m_pThread = GetThread();
- _ASSERTE(m_pThread != NULL);
-
-#ifdef _DEBUG
- m_pTransitionedToAD = m_pThread->GetDomain();
-#endif // _DEBUG
-}
-
-ReturnToPreviousAppDomainHolder::ReturnToPreviousAppDomainHolder()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- Init();
-}
-
-void ReturnToPreviousAppDomainHolder::ReturnToPreviousAppDomain()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- // Test your sanity - we should still be in the transitioned-to AD.
- PRECONDITION(m_pThread->GetDomain() == m_pTransitionedToAD);
- }
- CONTRACTL_END;
-
- {
- GCX_COOP();
- ::ReturnToPreviousAppDomain();
- }
-
- // Set the LastThrownObject as NULL since we have returned to a different
- // AD. Maintaining the reference to an object in the "returned-from" AD
- // will prevent the AD from getting unloaded.
- //
- // Setting to NULL does not require us to be in COOP mode.
- m_pThread->SafeSetLastThrownObject(NULL);
-}
-
-ReturnToPreviousAppDomainHolder::~ReturnToPreviousAppDomainHolder()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- if (m_fShouldReturnToPreviousAppDomain)
- {
- ReturnToPreviousAppDomain();
- }
-}
-
-// Reset the flag to indicate that reverting to previous AD is not required anymore.
-// This should be invoked when the call has successfully returned from the target execution context.
-//
-// By default, this flag is TRUE (see the contructor above) to enable automatic context
-// revert incase an exception goes past the transition.
-//
-// END_DOMAIN_TRANSITION_NO_EH_AT_TRANSITION macro uses it. See its implementation in threads.h
-// for usage.
-void ReturnToPreviousAppDomainHolder::SuppressRelease()
-{
- LIMITED_METHOD_CONTRACT;
-
- m_fShouldReturnToPreviousAppDomain = FALSE;
-}
-
-#endif // !DACCESS_COMPILE
-
#ifndef DACCESS_COMPILE
// This method will deliver the actual exception notification. Its assumed that the caller has done the necessary checks, including
// checking whether the delegate can be invoked for the exception's corruption severity.
#endif // FEATURE_CORRUPTING_EXCEPTIONS
#ifndef DACCESS_COMPILE
-// Switches to the previous AppDomain on the thread. See implementation for detailed comments.
-BOOL ReturnToPreviousAppDomain();
-
-// This is a generic holder that will enable you to revert to previous execution context (e.g. an AD).
-// Set it up *once* you have transitioned to the target context.
-class ReturnToPreviousAppDomainHolder
-{
-protected: // protected so that derived holder classes can also use them
- BOOL m_fShouldReturnToPreviousAppDomain;
- Thread * m_pThread;
-#ifdef _DEBUG
- AppDomain * m_pTransitionedToAD;
-#endif // _DEBUG
-
- void Init();
- void ReturnToPreviousAppDomain();
-
-public:
- ReturnToPreviousAppDomainHolder();
- ~ReturnToPreviousAppDomainHolder();
- void SuppressRelease();
-};
-
// exception filter invoked for unhandled exceptions on the entry point thread (thread 0)
LONG EntryPointFilter(PEXCEPTION_POINTERS pExceptionInfo, PVOID _pData);
-
#endif // !DACCESS_COMPILE
// Enum that defines the types of exception notification handlers
}
else
{
- _ASSERTE(targetAppDomain->GetDefaultContext());
-
if (!currentDomain->IsDefaultDomain())
{
// this means we are in some other domain, so need to return back out through the DoADCallback
{
WRAPPER_NO_CONTRACT;
- // Don't check app domains here - m_ReturnExecutionContext is in the parent frame's app domain
- (*fn)(dac_cast<PTR_PTR_Object>(PTR_HOST_MEMBER_TADDR(ContextTransitionFrame, this, m_ReturnExecutionContext)), sc, 0);
- LOG((LF_GC, INFO3, " " FMT_ADDR "\n", DBG_ADDR(m_ReturnExecutionContext) ));
-
// Don't check app domains here - m_LastThrownObjectInParentContext is in the parent frame's app domain
(*fn)(dac_cast<PTR_PTR_Object>(PTR_HOST_MEMBER_TADDR(ContextTransitionFrame, this, m_LastThrownObjectInParentContext)), sc, 0);
LOG((LF_GC, INFO3, " " FMT_ADDR "\n", DBG_ADDR(m_LastThrownObjectInParentContext) ));
#include "object.h"
#include <stddef.h>
#include "siginfo.hpp"
-// context headers
-#include "context.h"
#include "method.hpp"
#include "stackwalk.h"
#include "stubmgr.h"
return (ptr != NULL) ? *PTR_PCODE(ptr) : NULL;
}
- virtual PTR_Context* GetReturnContextAddr()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return NULL;
- }
-
- Context *GetReturnContext()
- {
- WRAPPER_NO_CONTRACT;
- SUPPORTS_DAC;
- PTR_Context* ppReturnContext = GetReturnContextAddr();
- if (! ppReturnContext)
- return NULL;
- return *ppReturnContext;
- }
-
AppDomain *GetReturnDomain()
{
- WRAPPER_NO_CONTRACT;
- SUPPORTS_DAC;
-
- if (! GetReturnContext())
- return NULL;
- return GetReturnContext()->GetDomain();
+ LIMITED_METHOD_CONTRACT;
+ return NULL;
}
#ifndef DACCESS_COMPILE
_ASSERTE(ptr != NULL);
*(TADDR*)ptr = val;
}
-
-#ifndef DACCESS_COMPILE
- void SetReturnContext(Context *pReturnContext)
- {
- WRAPPER_NO_CONTRACT;
- PTR_Context* ppReturnContext = GetReturnContextAddr();
- _ASSERTE(ppReturnContext);
- *ppReturnContext = pReturnContext;
- }
-#endif
-
- void SetReturnExecutionContext(OBJECTREF ref)
- {
- WRAPPER_NO_CONTRACT;
- Object **pRef = GetReturnExecutionContextAddr();
- if (pRef != NULL)
- *pRef = OBJECTREFToObject(ref);
- }
-
- OBJECTREF GetReturnExecutionContext()
- {
- WRAPPER_NO_CONTRACT;
- Object **pRef = GetReturnExecutionContextAddr();
- if (pRef == NULL)
- return NULL;
- else
- return ObjectToOBJECTREF(*pRef);
- }
#endif // #ifndef DACCESS_COMPILE
PTR_GSCookie GetGSCookiePtr()
#if defined(DACCESS_COMPILE)
friend class DacDbiInterfaceImpl;
#endif // DACCESS_COMPILE
-#ifdef FEATURE_COMINTEROP
- friend void COMToCLRWorkerBodyWithADTransition(Thread *pThread, ComMethodFrame *pFrame, ComCallWrapper *pWrap, UINT64 *pRetValOut);
-#endif // FEATURE_COMINTEROP
PTR_Frame Next()
{
class ContextTransitionFrame : public Frame
{
private:
- PTR_Context m_pReturnContext;
- PTR_Object m_ReturnExecutionContext;
PTR_Object m_LastThrownObjectInParentContext;
ULONG_PTR m_LockCount; // Number of locks the thread takes
// before the transition.
public:
virtual void GcScanRoots(promote_func *fn, ScanContext* sc);
- virtual PTR_Context* GetReturnContextAddr()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return &m_pReturnContext;
- }
-
- virtual Object **GetReturnExecutionContextAddr()
- {
- LIMITED_METHOD_CONTRACT;
- return (Object **) &m_ReturnExecutionContext;
- }
-
OBJECTREF GetLastThrownObjectInParentContext()
{
return ObjectToOBJECTREF(m_LastThrownObjectInParentContext);
#ifndef DACCESS_COMPILE
ContextTransitionFrame()
- : m_pReturnContext(NULL)
- , m_ReturnExecutionContext(NULL)
- , m_LastThrownObjectInParentContext(NULL)
+ : m_LastThrownObjectInParentContext(NULL)
, m_LockCount(0)
{
LIMITED_METHOD_CONTRACT;
#ifndef CROSSGEN_COMPILE
-// from clr/src/vm/threads.h
-#define Thread_m_Context 0x34
-ASMCONSTANTS_C_ASSERT(Thread_m_Context == offsetof(Thread, m_Context))
-
#define Thread_m_State 0x04
ASMCONSTANTS_C_ASSERT(Thread_m_State == offsetof(Thread, m_State))
#endif // CROSSGEN_COMPILE
class Thread;
class BaseDomain;
class Assembly;
-class Context;
class DomainAssembly;
class AssemblyNative;
class WaitHandleNative;
Thread *pThread = reinterpret_cast<Thread *>(threadId);
// Get the context for the Thread* provided
- Context *pContext = pThread->GetContext();
+ AppDomain *pContext = pThread->GetDomain(); // Context is same as AppDomain in CoreCLR
_ASSERTE(pContext);
// If there's no current context, return incomplete info
PRECONDITION(CheckPointer(pPropertyProvider));
PRECONDITION(IsSimpleTearOff(pPropertyProvider));
PRECONDITION(CheckPointer(ppProperty, NULL_OK));
- PRECONDITION(!MapIUnknownToWrapper(pPropertyProvider)->NeedToSwitchDomains(GetThread()));
}
CONTRACTL_END;
PRECONDITION(CheckPointer(pPropertyProvider));
PRECONDITION(IsSimpleTearOff(pPropertyProvider));
PRECONDITION(CheckPointer(ppProperty, NULL_OK));
- PRECONDITION(!MapIUnknownToWrapper(pPropertyProvider)->NeedToSwitchDomains(GetThread()));
}
CONTRACTL_END;
PRECONDITION(CheckPointer(pPropertyProvider));
PRECONDITION(IsSimpleTearOff(pPropertyProvider));
PRECONDITION(CheckPointer(phstrStringRepresentation, NULL_OK));
- PRECONDITION(!MapIUnknownToWrapper(pPropertyProvider)->NeedToSwitchDomains(GetThread()));
}
CONTRACTL_END;
PRECONDITION(CheckPointer(pPropertyProvider));
PRECONDITION(IsSimpleTearOff(pPropertyProvider));
PRECONDITION(CheckPointer(pTypeIdentifier));
- PRECONDITION(!MapIUnknownToWrapper(pPropertyProvider)->NeedToSwitchDomains(GetThread()));
}
CONTRACTL_END;
PRECONDITION(CheckPointer(pStringable));
PRECONDITION(IsSimpleTearOff(pStringable));
PRECONDITION(CheckPointer(pResult, NULL_OK));
- PRECONDITION(!MapIUnknownToWrapper(pStringable)->NeedToSwitchDomains(GetThread()));
}
CONTRACTL_END;
if ((g_fEEShutDown & ShutDown_Finalize2) || g_fForbidEnterEE)
return FALSE;
- return (!pWrap->NeedToSwitchDomains(pThread));
+ return TRUE;
}
BOOL IsCurrentDomainValid(ComCallWrapper* pWrap)
struct AppDomainSwitchToPreemptiveHelperArgs
{
- Context::ADCallBackFcnType pRealCallback;
+ ADCallBackFcnType pRealCallback;
void* pRealArgs;
};
pArgs->pRealCallback(pArgs->pRealArgs);
}
-VOID AppDomainDoCallBack(ComCallWrapper* pWrap, Context::ADCallBackFcnType pTarget, LPVOID pArgs, HRESULT* phr)
+VOID AppDomainDoCallBack(ComCallWrapper* pWrap, ADCallBackFcnType pTarget, LPVOID pArgs, HRESULT* phr)
{
CONTRACTL
{
BEGIN_EXTERNAL_ENTRYPOINT(phr)
{
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
- Thread *pThread = GET_THREAD();
-
- ADID targetADID;
- Context *pTargetContext;
- if (pWrap->NeedToSwitchDomains(pThread, &targetADID, &pTargetContext))
- {
- // call ourselves again through DoCallBack with a domain transition.
- // We need to switch back to preemptive GC mode before we call the
- // real target method.
- AppDomainSwitchToPreemptiveHelperArgs args = {(Context::ADCallBackFcnType)pTarget, pArgs};
- pThread->DoContextCallBack(targetADID, pTargetContext, AppDomainSwitchToPreemptiveHelper, &args);
- }
- else
- {
- // make the call directly not forgetting to switch to preemptive GC mode
- GCX_PREEMP();
- ((Context::ADCallBackFcnType)pTarget)(pArgs);
- }
+ // make the call directly not forgetting to switch to preemptive GC mode
+ GCX_PREEMP();
+ ((ADCallBackFcnType)pTarget)(pArgs);
}
END_EXTERNAL_ENTRYPOINT;
}
syncState.m_EnterCount = LeaveMonitorCompletely();
_ASSERTE(syncState.m_EnterCount > 0);
- Context* targetContext;
- targetContext = pCurThread->GetContext();
- _ASSERTE(targetContext);
- Context* defaultContext;
- defaultContext = pCurThread->GetDomain()->GetDefaultContext();
- _ASSERTE(defaultContext);
- _ASSERTE( exitContext==NULL || targetContext == defaultContext);
- {
- isTimedOut = pCurThread->Block(timeOut, &syncState);
- }
+ isTimedOut = pCurThread->Block(timeOut, &syncState);
}
GCPROTECT_END();
m_Monitor.DecrementTransientPrecious();
m_fDisableComObjectEagerCleanup = false;
#endif //FEATURE_COMINTEROP
m_fHasDeadThreadBeenConsideredForGCTrigger = false;
- m_Context = NULL;
m_TraceCallCount = 0;
m_ThrewControlForThread = 0;
m_OSContext = NULL;
m_threadPoolCompletionCount = 0;
Thread *pThread = GetThread();
- _ASSERTE(SystemDomain::System()->DefaultDomain()->GetDefaultContext());
InitContext();
- _ASSERTE(m_Context);
if (pThread)
{
- _ASSERTE(pThread->GetDomain() && pThread->GetDomain()->GetDefaultContext());
+ _ASSERTE(pThread->GetDomain());
// Start off the new thread in the default context of
// the creating thread's appDomain. This could be changed by SetDelegate
SetKickOffDomainId(pThread->GetDomain()->GetId());
FrameWithCookie<ContextTransitionFrame> _ctx_trans_Frame;
ContextTransitionFrame* _ctx_trans_pFrame = &_ctx_trans_Frame;
- _ctx_trans_pThread->EnterContextRestricted(
- pTargetDomain->GetDefaultContext(),
- _ctx_trans_pFrame);
-
args->pCtxFrame = _ctx_trans_pFrame;
TESTHOOKCALL(EnteredAppDomain((TargetDomain.m_dwId)));
/* work around unreachable code warning */
LOG((LF_APPDOMAIN, LL_INFO1000, "LEAVE_DOMAIN(%s, %s, %d)\n",
__FUNCTION__, __FILE__, __LINE__));
- _ctx_trans_pThread->ReturnToContext(_ctx_trans_pFrame);
-
#ifdef FEATURE_TESTHOOKS
TESTHOOKCALL(LeftAppDomain(TargetDomain.m_dwId));
#endif
CONTRACTL_END;
// this should only be called when initializing a thread
- _ASSERTE(m_Context == NULL);
_ASSERTE(m_pDomain == NULL);
GCX_COOP_NO_THREAD_BROKEN();
- m_Context = SystemDomain::System()->DefaultDomain()->GetDefaultContext();
- m_pDomain = m_Context->GetDomain();
+ m_pDomain = SystemDomain::System()->DefaultDomain();
_ASSERTE(m_pDomain);
m_pDomain->ThreadEnter(this, NULL);
}
}
CONTRACTL_END;
- // if one is null, both must be
- _ASSERTE(m_pDomain && m_Context || ! (m_pDomain && m_Context));
-
if (!m_pDomain)
return;
#ifdef FEATURE_COMINTEROP
m_fDisableComObjectEagerCleanup = false;
#endif //FEATURE_COMINTEROP
- m_Context = NULL;
}
-
-void Thread::DoContextCallBack(ADID appDomain, Context *pContext, Context::ADCallBackFcnType pTarget, LPVOID args)
-{
- //Do not deference pContext if it's not from the current appdomain
-
-#ifdef _DEBUG
- TADDR espVal = (TADDR)GetCurrentSP();
-
- LOG((LF_APPDOMAIN, LL_INFO100, "Thread::DoADCallBack Calling %p at esp %p in [%d]\n",
- pTarget, espVal, appDomain.m_dwId));
-#endif
- _ASSERTE(GetThread()->GetContext() != pContext);
- Thread* pThread = GetThread();
-
- // Get the default context for the current domain as well as for the
- // destination domain.
- AppDomain* pCurrDomain = pThread->GetContext()->GetDomain();
- Context* pCurrDefCtx = pCurrDomain->GetDefaultContext();
- BOOL bDefaultTargetCtx=FALSE;
-
- AppDomain* ad = SystemDomain::GetAppDomainFromId(appDomain, ADV_CURRENTAD);
- bDefaultTargetCtx=(ad->GetDefaultContext()==pContext);
-
- if (pCurrDefCtx == pThread->GetContext() && bDefaultTargetCtx)
- {
- ENTER_DOMAIN_ID(appDomain);
- (pTarget)(args);
- END_DOMAIN_TRANSITION;
- }
- else
- {
- UNREACHABLE();
- }
- LOG((LF_APPDOMAIN, LL_INFO100, "Thread::DoADCallBack Done at esp %p\n", espVal));
-}
-
-void Thread::EnterContextRestricted(Context *pContext, ContextTransitionFrame *pFrame)
-{
- CONTRACTL {
- THROWS;
- MODE_COOPERATIVE;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- _ASSERTE(GetThread() == this);
- _ASSERTE(pContext); // should never enter a null context
- _ASSERTE(m_Context); // should always have a current context
-
- AppDomain *pPrevDomain = m_pDomain;
- AppDomain *pDomain = pContext->GetDomain();
- // and it should always have an AD set
- _ASSERTE(pDomain);
-
- pFrame->SetReturnContext(m_Context);
- pFrame->SetReturnExecutionContext(NULL);
-
- if (pPrevDomain != pDomain)
- {
- pFrame->SetLockCount(m_dwBeginLockCount);
- m_dwBeginLockCount = m_dwLockCount;
- }
-
- if (m_Context == pContext) {
- _ASSERTE(m_Context->GetDomain() == pContext->GetDomain());
- return;
- }
-
- LOG((LF_APPDOMAIN, LL_INFO1000, "%sThread::EnterContext from (%p) [%d] (count %d)\n",
- FinalizerThread::IsCurrentThreadFinalizer() ? "FT: " : "",
- m_Context, m_Context->GetDomain()->GetId().m_dwId,
- m_Context->GetDomain()->GetThreadEnterCount()));
- LOG((LF_APPDOMAIN, LL_INFO1000, " into (%p) [%d] (count %d)\n", pContext,
- pContext->GetDomain()->GetId().m_dwId,
- pContext->GetDomain()->GetThreadEnterCount()));
-
-#ifdef _DEBUG_ADUNLOAD
- printf("Thread::EnterContext %x from (%8.8x) [%d]\n", GetThreadId(), m_Context,
- m_Context ? m_Context->GetDomain()->GetId() : -1);
- printf(" into (%8.8x) [%d] %S\n", pContext,
- pContext->GetDomain()->GetId());
-#endif
-
- CantStopHolder hCantStop;
-
- bool fChangedDomains = m_pDomain != pDomain;
- if (fChangedDomains)
- {
-
-#ifdef FEATURE_STACK_PROBE
- if (pDomain == SystemDomain::System()->DefaultDomain() &&
- GetEEPolicy()->GetActionOnFailure(FAIL_StackOverflow) == eRudeUnloadAppDomain)
- {
- // Make sure default domain does not see SO.
- // probe for our entry point amount and throw if not enough stack
- RetailStackProbe(ADJUST_PROBE(DEFAULT_ENTRY_PROBE_AMOUNT*2), this);
- }
-#endif
-
- _ASSERTE(pFrame);
-
- STRESS_LOG1(LF_APPDOMAIN, LL_INFO100000, "Entering into ADID=%d\n", pDomain->GetId().m_dwId);
-
-
- //
- // Store the last thrown object in the ContextTransitionFrame before we null it out
- // to prevent it from leaking into the domain we are transitionning into.
- //
-
- pFrame->SetLastThrownObjectInParentContext(LastThrownObject());
- SafeSetLastThrownObject(NULL);
- }
-
- m_Context = pContext;
- pFrame->Push();
-
-#ifdef _DEBUG_ADUNLOAD
- printf("Thread::EnterContext %x,%8.8x push? %d current frame is %8.8x\n", GetThreadId(), this, 1, GetFrame());
-#endif
-
- if (fChangedDomains)
- {
- pDomain->ThreadEnter(this, pFrame);
-
-#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
- if (g_fEnableARM)
- {
- // Update previous AppDomain's count of processor usage by threads executing within it.
- pPrevDomain->UpdateProcessorUsage(QueryThreadProcessorUsage());
- FireEtwThreadDomainEnter((ULONGLONG)this, (ULONGLONG)pDomain, GetClrInstanceId());
- }
-#endif // FEATURE_APPDOMAIN_RESOURCE_MONITORING
-
- m_pDomain = pDomain;
- SetAppDomain(m_pDomain);
- }
-}
-
-// main difference between EnterContext and ReturnToContext is that are allowed to return
-// into a domain that is unloading but cannot enter a domain that is unloading
-void Thread::ReturnToContext(ContextTransitionFrame *pFrame)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
- _ASSERTE(GetThread() == this);
-
- Context *pReturnContext = pFrame->GetReturnContext();
- _ASSERTE(pReturnContext);
-
- ADID pADOnStack;
-
- AppDomain *pReturnDomain = pReturnContext->GetDomain();
- AppDomain* pCurrentDomain = m_pDomain;
-
- if (m_Context == pReturnContext)
- {
- return;
- }
-
- GCX_COOP();
-
- LOG((LF_APPDOMAIN, LL_INFO1000, "%sThread::ReturnToContext from (%p) [%d] (count %d)\n",
- FinalizerThread::IsCurrentThreadFinalizer() ? "FT: " : "",
- m_Context, m_Context->GetDomain()->GetId().m_dwId,
- m_Context->GetDomain()->GetThreadEnterCount()));
- LOG((LF_APPDOMAIN, LL_INFO1000, " into (%p) [%d] (count %d)\n", pReturnContext,
- pReturnContext->GetDomain()->GetId().m_dwId,
- pReturnContext->GetDomain()->GetThreadEnterCount()));
-
-#ifdef _DEBUG_ADUNLOAD
- printf("Thread::ReturnToContext %x from (%p) [%d]\n", GetThreadId(), m_Context,
- m_Context->GetDomain()->GetId(),
- printf(" into (%p) [%d]\n", pReturnContext,
- pReturnContext->GetDomain()->GetId(),
- m_Context->GetDomain()->GetThreadEnterCount());
-#endif
-
- CantStopHolder hCantStop;
-
- m_Context = pReturnContext;
-
- pFrame->Pop();
-
-#ifdef _DEBUG_ADUNLOAD
- printf("Thread::ReturnToContext %x,%8.8x pop? %d current frame is %8.8x\n", GetThreadId(), this, 1, GetFrame());
-#endif
-
- return;
-}
-
-
-void Thread::ReturnToContextAndThrow(ContextTransitionFrame* pFrame, EEException* pEx, BOOL* pContextSwitched)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- PRECONDITION(CheckPointer(pContextSwitched));
- }
- CONTRACTL_END;
-#ifdef FEATURE_TESTHOOKS
- ADID adid=GetAppDomain()->GetId();
-#endif
- ReturnToContext(pFrame);
- *pContextSwitched=TRUE;
-#ifdef FEATURE_TESTHOOKS
- TESTHOOKCALL(LeftAppDomain(adid.m_dwId));
-#endif
-
- COMPlusThrow(CLRException::GetThrowableFromException(pEx));
-}
-
-void Thread::ReturnToContextAndOOM(ContextTransitionFrame* pFrame)
-{
-
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-#ifdef FEATURE_TESTHOOKS
- ADID adid=GetAppDomain()->GetId();
-#endif
-
- ReturnToContext(pFrame);
-#ifdef FEATURE_TESTHOOKS
- TESTHOOKCALL(LeftAppDomain(adid.m_dwId));
-#endif
-
- COMPlusThrowOM();
-}
-
-
void DECLSPEC_NORETURN Thread::RaiseCrossContextException(Exception* pExOrig, ContextTransitionFrame* pFrame)
{
CONTRACTL
AppDomain* pUnsafeAppDomain;
BOOL bDomainIsAsID;
- Context::ADCallBackFcnType pTarget;
+ ADCallBackFcnType pTarget;
LPVOID args;
UnhandledExceptionLocation filterType;
ManagedThreadCallStateFlags flags;
LIMITED_METHOD_CONTRACT;
return bDomainIsAsID?(pApp->GetId()==pAppDomainId):(pUnsafeAppDomain==pApp);
}
- ManagedThreadCallState(ADID AppDomainId,Context::ADCallBackFcnType Target,LPVOID Args,
+ ManagedThreadCallState(ADID AppDomainId,ADCallBackFcnType Target,LPVOID Args,
UnhandledExceptionLocation FilterType, ManagedThreadCallStateFlags Flags):
pAppDomainId(AppDomainId),
pUnsafeAppDomain(NULL),
LIMITED_METHOD_CONTRACT;
};
protected:
- ManagedThreadCallState(AppDomain* AppDomain,Context::ADCallBackFcnType Target,LPVOID Args,
+ ManagedThreadCallState(AppDomain* AppDomain,ADCallBackFcnType Target,LPVOID Args,
UnhandledExceptionLocation FilterType, ManagedThreadCallStateFlags Flags):
pAppDomainId(ADID(0)),
pUnsafeAppDomain(AppDomain),
{
LIMITED_METHOD_CONTRACT;
};
- void InitForFinalizer(AppDomain* AppDomain,Context::ADCallBackFcnType Target,LPVOID Args)
+ void InitForFinalizer(AppDomain* AppDomain,ADCallBackFcnType Target,LPVOID Args)
{
LIMITED_METHOD_CONTRACT;
filterType=FinalizerThread;
args=Args;
};
- friend void ManagedThreadBase_NoADTransition(Context::ADCallBackFcnType pTarget,
+ friend void ManagedThreadBase_NoADTransition(ADCallBackFcnType pTarget,
UnhandledExceptionLocation filterType);
friend void ManagedThreadBase::FinalizerAppDomain(AppDomain* pAppDomain,
- Context::ADCallBackFcnType pTarget,
+ ADCallBackFcnType pTarget,
LPVOID args,
ManagedThreadCallState *pTurnAround);
};
}
PAL_FINALLY
{
- // If we had a breakpoint exception that has gone unhandled,
- // then switch to the correct AD context. Its fine to do this
- // here because:
- //
- // 1) We are in an unwind (this is a C++ destructor).
- // 2) SetFrame (below) does validation to be in the correct AD context. Thus,
- // this should be done before that.
- if (fHadException && (GetCurrentExceptionCode() == STATUS_BREAKPOINT))
- {
- ReturnToPreviousAppDomain();
- }
catchFrame.Pop();
}
PAL_ENDTRY;
// 1. Establish the base of a managed thread, and switch to the correct AppDomain.
static void ManagedThreadBase_FullTransitionWithAD(ADID pAppDomain,
- Context::ADCallBackFcnType pTarget,
+ ADCallBackFcnType pTarget,
LPVOID args,
UnhandledExceptionLocation filterType)
{
// 2. Establish the base of a managed thread, but the AppDomain transition must be
// deferred until later.
-void ManagedThreadBase_NoADTransition(Context::ADCallBackFcnType pTarget,
+void ManagedThreadBase_NoADTransition(ADCallBackFcnType pTarget,
UnhandledExceptionLocation filterType)
{
CONTRACTL
// And here are the various exposed entrypoints for base thread behavior
// The 'new Thread(...).Start()' case from COMSynchronizable kickoff thread worker
-void ManagedThreadBase::KickOff(ADID pAppDomain, Context::ADCallBackFcnType pTarget, LPVOID args)
+void ManagedThreadBase::KickOff(ADID pAppDomain, ADCallBackFcnType pTarget, LPVOID args)
{
WRAPPER_NO_CONTRACT;
ManagedThreadBase_FullTransitionWithAD(pAppDomain, pTarget, args, ManagedThread);
}
// The IOCompletion, QueueUserWorkItem, AddTimer, RegisterWaitForSingleObject cases in the ThreadPool
-void ManagedThreadBase::ThreadPool(ADID pAppDomain, Context::ADCallBackFcnType pTarget, LPVOID args)
+void ManagedThreadBase::ThreadPool(ADID pAppDomain, ADCallBackFcnType pTarget, LPVOID args)
{
WRAPPER_NO_CONTRACT;
ManagedThreadBase_FullTransitionWithAD(pAppDomain, pTarget, args, ThreadPoolThread);
// The Finalizer thread establishes exception handling at its base, but defers all the AppDomain
// transitions.
-void ManagedThreadBase::FinalizerBase(Context::ADCallBackFcnType pTarget)
+void ManagedThreadBase::FinalizerBase(ADCallBackFcnType pTarget)
{
WRAPPER_NO_CONTRACT;
ManagedThreadBase_NoADTransition(pTarget, FinalizerThread);
}
void ManagedThreadBase::FinalizerAppDomain(AppDomain *pAppDomain,
- Context::ADCallBackFcnType pTarget,
+ ADCallBackFcnType pTarget,
LPVOID args,
ManagedThreadCallState *pTurnAround)
{
{
m_pDomain->EnumMemoryRegions(flags, true);
}
-
- if (m_Context.IsValid())
- {
- m_Context->EnumMemoryRegions(flags);
- }
}
if (m_debuggerFilterContext.IsValid())
#include "util.hpp"
#include "eventstore.hpp"
#include "argslot.h"
-#include "context.h"
#include "regdisp.h"
#include "mscoree.h"
#include "gcheaputilities.h"
typedef DPTR(struct ThreadLocalBlock) PTR_ThreadLocalBlock;
typedef DPTR(PTR_ThreadLocalBlock) PTR_PTR_ThreadLocalBlock;
+typedef void(*ADCallBackFcnType)(LPVOID);
+
#include "stackwalktypes.h"
#include "log.h"
#include "stackingallocator.h"
inline void IncLockCount() { }
inline void DecLockCount() { }
- void EnterContextRestricted(Context* c, ContextTransitionFrame* pFrame) { }
-
static LPVOID GetStaticFieldAddress(FieldDesc *pFD) { return NULL; }
PTR_AppDomain GetDomain() { return ::GetAppDomain(); }
friend class ThreadStore;
friend class ThreadSuspend;
friend class SyncBlock;
- friend class Context;
friend struct PendingSync;
friend class AppDomain;
friend class ThreadNative;
}
#endif // FEATURE_COMINTEROP && !DACCESS_COMPILE
- // The context within which this thread is executing. As the thread crosses
- // context boundaries, the context mechanism adjusts this so it's always
- // current.
- // <TODO>@TODO cwb: When we add COM+ 1.0 Context Interop, this should get moved out
- // of the Thread object and into its own slot in the TLS.</TODO>
- // The address of the context object is also used as the ContextID!
- PTR_Context m_Context;
+ // Lock thread is trying to acquire
+ VolatilePtr<DeadlockAwareLock> m_pBlockingLock;
public:
// or interlocked operations to get a new hash code;
DWORD m_dwHashCodeSeed;
- // Lock thread is trying to acquire
- VolatilePtr<DeadlockAwareLock> m_pBlockingLock;
-
public:
inline BOOL HasLockInCurrentDomain()
return PTR_ThreadExceptionState(PTR_HOST_MEMBER_TADDR(Thread, this, m_ExceptionState));
}
- // Access to the Context this thread is executing in.
- Context *GetContext()
- {
- LIMITED_METHOD_CONTRACT;
- SUPPORTS_DAC;
-#ifndef DACCESS_COMPILE
-
- // if another thread is asking about our thread, we could be in the middle of an AD transition so
- // the context and AD may not match if have set one but not the other. Can live without checking when
- // another thread is asking it as this method is mostly called on our own thread so will mostly get the
- // checking. If are int the middle of a transition, this could return either the old or the new AD.
- // But no matter what we do, such as lock on the transition, by the time are done could still have
- // changed right after we asked, so really no point.
- _ASSERTE((this != GetThreadNULLOk()) || (m_Context == NULL && m_pDomain == NULL) || (m_Context->GetDomain() == m_pDomain) || g_fEEShutDown);
-#endif // DACCESS_COMPILE
- return m_Context;
- }
-
- void DoContextCallBack(ADID appDomain, Context* c , Context::ADCallBackFcnType pTarget, LPVOID args);
-
- // Except for security and the call in from the remoting code in mscorlib, you should never do an
- // AppDomain transition directly through these functions. Rather, you should use DoADCallBack above
- // to call into managed code to perform the transition for you so that the correct policy code etc
- // is run on the transition,
- void EnterContextRestricted(Context* c, ContextTransitionFrame* pFrame);
- void ReturnToContext(ContextTransitionFrame *pFrame);
-
public:
void DECLSPEC_NORETURN RaiseCrossContextException(Exception* pEx, ContextTransitionFrame* pFrame);
// ClearContext are to be called only during shutdown
void ClearContext();
-private:
- void ReturnToContextAndThrow(ContextTransitionFrame* pFrame, EEException* pEx, BOOL* pContextSwitched);
- void ReturnToContextAndOOM(ContextTransitionFrame* pFrame);
-
private:
// don't ever call these except when creating thread!!!!!
void InitContext();
(_ctx_trans_pCurrDomain==NULL || \
(_ctx_trans_pCurrDomain->GetId() != _ctx_trans_pDestDomainId))) \
{ \
- AppDomain* _ctx_trans_ad = SystemDomain::GetAppDomainFromId(_ctx_trans_pDestDomainId, ADV_CURRENTAD); \
- \
- _ctx_trans_ad->EnterContext(_ctx_trans_pThread, \
- _ctx_trans_ad->GetDefaultContext(), \
- _ctx_trans_pFrame); \
- \
_ctx_trans_fTransitioned = true; \
}
TESTHOOKCALL(AppDomainCanBeUnloaded(_ctx_trans_pDestDomain->GetId().m_dwId,FALSE)); \
GCX_FORBID(); \
\
- _ctx_trans_pThread->EnterContextRestricted( \
- _ctx_trans_pDestDomain->GetDefaultContext(), \
- _ctx_trans_pFrame); \
- \
_ctx_trans_fTransitioned = true; \
}
LOG((LF_APPDOMAIN, LL_INFO1000, "LEAVE_DOMAIN(%s, %s, %d)\n", \
__FUNCTION__, __FILE__, __LINE__)); \
\
- if (_ctx_trans_fTransitioned) \
- { \
- GCX_FORBID(); \
- _ctx_trans_pThread->ReturnToContext(_ctx_trans_pFrame); \
- } \
TESTHOOKCALL(LeftAppDomain(_ctx_trans_pDestDomainId.m_dwId)); \
DEBUG_ASSURE_NO_RETURN_END(DOMAIN) \
}
CheckADValidity(_pDestDomain,ADValidityKind); \
ENTER_DOMAIN_SETUPVARS(GetThread(), true) \
ENTER_DOMAIN_SWITCH_CTX_BY_ADPTR(_ctx_trans_pThread->GetDomain(), _pDestDomain) \
- TESTHOOKCALL(EnteredAppDomain((_pDestDomain)->GetId().m_dwId)); \
- ReturnToPreviousAppDomainHolder __returnToPreviousAppDomainHolder;
+ TESTHOOKCALL(EnteredAppDomain((_pDestDomain)->GetId().m_dwId));
#define ENTER_DOMAIN_ID_NO_EH_AT_TRANSITION_PREDICATED(_pDestDomain,_predicate_expr) \
TESTHOOKCALL(EnteringAppDomain(_pDestDomain.m_dwId)) ; \
ENTER_DOMAIN_SETUPVARS(GetThread(), _predicate_expr) \
ENTER_DOMAIN_SWITCH_CTX_BY_ADID(_ctx_trans_pThread->GetDomain(), _pDestDomain, FALSE) \
- TESTHOOKCALL(EnteredAppDomain(_pDestDomain.m_dwId)); \
- ReturnToPreviousAppDomainHolder __returnToPreviousAppDomainHolder;
+ TESTHOOKCALL(EnteredAppDomain(_pDestDomain.m_dwId));
#define ENTER_DOMAIN_ID_NO_EH_AT_TRANSITION(_pDestDomain) \
ENTER_DOMAIN_ID_NO_EH_AT_TRANSITION_PREDICATED(_pDestDomain,true)
LOG((LF_APPDOMAIN, LL_INFO1000, "LEAVE_DOMAIN(%s, %s, %d)\n", \
__FUNCTION__, __FILE__, __LINE__)); \
\
- if (_ctx_trans_fTransitioned) \
- { \
- GCX_FORBID(); \
- _ctx_trans_pThread->ReturnToContext(_ctx_trans_pFrame); \
- } \
__returnToPreviousAppDomainHolder.SuppressRelease(); \
TESTHOOKCALL(LeftAppDomain(_ctx_trans_pDestDomainId.m_dwId)); \
DEBUG_ASSURE_NO_RETURN_END(DOMAIN) \
{
// The 'new Thread(...).Start()' case from COMSynchronizable kickoff thread worker
static void KickOff(ADID pAppDomain,
- Context::ADCallBackFcnType pTarget,
+ ADCallBackFcnType pTarget,
LPVOID args);
// The IOCompletion, QueueUserWorkItem, AddTimer, RegisterWaitForSingleObject cases in
// the ThreadPool
- static void ThreadPool(ADID pAppDomain, Context::ADCallBackFcnType pTarget, LPVOID args);
+ static void ThreadPool(ADID pAppDomain, ADCallBackFcnType pTarget, LPVOID args);
// The Finalizer thread separates the tasks of establishing exception handling at its
// base and transitioning into AppDomains. The turnaround structure that ties the 2 calls together
// For the case (like Finalization) where the base transition and the AppDomain transition are
// separated, an opaque structure is used to tie together the two calls.
- static void FinalizerBase(Context::ADCallBackFcnType pTarget);
+ static void FinalizerBase(ADCallBackFcnType pTarget);
static void FinalizerAppDomain(AppDomain* pAppDomain,
- Context::ADCallBackFcnType pTarget,
+ ADCallBackFcnType pTarget,
LPVOID args,
ManagedThreadCallState *pTurnAround);
};
typedef StateHolder<DoNothing,DeadlockAwareLock::ReleaseBlockingLock> BlockingLockHolder;
};
-inline Context* GetCurrentContext()
-{
- CONTRACTL {
- SO_TOLERANT;
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- return GetThread()->GetContext();
-}
-
inline void SetTypeHandleOnThreadForAlloc(TypeHandle th)
{
// We are doing this unconditionally even though th is only used by ETW events in GC. When the ETW