Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions src/coreclr/vm/appdomain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3709,7 +3709,9 @@ BOOL AppDomain::AddFileToCache(AssemblySpec* pSpec, PEAssembly *pFile, BOOL fAll
}
CONTRACTL_END;

CrstHolder holder(&m_DomainCacheCrst);
GCX_PREEMP();
DomainCacheCrstHolderForGCCoop holder(this);

// !!! suppress exceptions
if(!m_AssemblyCache.StoreFile(pSpec, pFile) && !fAllowFailure)
{
Expand Down Expand Up @@ -3739,7 +3741,9 @@ BOOL AppDomain::AddAssemblyToCache(AssemblySpec* pSpec, DomainAssembly *pAssembl
}
CONTRACTL_END;

CrstHolder holder(&m_DomainCacheCrst);
GCX_PREEMP();
DomainCacheCrstHolderForGCCoop holder(this);

// !!! suppress exceptions
BOOL bRetVal = m_AssemblyCache.StoreAssembly(pSpec, pAssembly);
return bRetVal;
Expand All @@ -3760,7 +3764,9 @@ BOOL AppDomain::AddExceptionToCache(AssemblySpec* pSpec, Exception *ex)
if (ex->IsTransient())
return TRUE;

CrstHolder holder(&m_DomainCacheCrst);
GCX_PREEMP();
DomainCacheCrstHolderForGCCoop holder(this);

// !!! suppress exceptions
return m_AssemblyCache.StoreException(pSpec, ex);
}
Expand All @@ -3778,7 +3784,7 @@ void AppDomain::AddUnmanagedImageToCache(LPCWSTR libraryName, NATIVE_LIBRARY_HAN
}
CONTRACTL_END;

CrstHolder lock(&m_DomainCacheCrst);
DomainCacheCrstHolderForGCPreemp lock(this);

const UnmanagedImageCacheEntry *existingEntry = m_unmanagedCache.LookupPtr(libraryName);
if (existingEntry != NULL)
Expand Down Expand Up @@ -3808,7 +3814,8 @@ NATIVE_LIBRARY_HANDLE AppDomain::FindUnmanagedImageInCache(LPCWSTR libraryName)
}
CONTRACT_END;

CrstHolder lock(&m_DomainCacheCrst);
DomainCacheCrstHolderForGCPreemp lock(this);

const UnmanagedImageCacheEntry *existingEntry = m_unmanagedCache.LookupPtr(libraryName);
if (existingEntry == NULL)
RETURN NULL;
Expand Down Expand Up @@ -3850,7 +3857,8 @@ BOOL AppDomain::RemoveAssemblyFromCache(DomainAssembly* pAssembly)
}
CONTRACTL_END;

CrstHolder holder(&m_DomainCacheCrst);
GCX_PREEMP();
DomainCacheCrstHolderForGCCoop holder(this);

return m_AssemblyCache.RemoveAssembly(pAssembly);
}
Expand Down
24 changes: 24 additions & 0 deletions src/coreclr/vm/appdomain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1171,6 +1171,30 @@ class BaseDomain
};
friend class LockHolder;

// To be used when the thread will remain in preemptive GC mode while holding the lock
class DomainCacheCrstHolderForGCPreemp : private CrstHolder
{
public:
DomainCacheCrstHolderForGCPreemp(BaseDomain *pD)
: CrstHolder(&pD->m_DomainCacheCrst)
{
WRAPPER_NO_CONTRACT;
}
};

// To be used when the thread may enter cooperative GC mode while holding the lock. The thread enters a
// forbid-suspend-for-debugger region along with acquiring the lock, such that it would not suspend for the debugger while
// holding the lock, as that may otherwise cause a FuncEval to deadlock when trying to acquire the lock.
class DomainCacheCrstHolderForGCCoop : private CrstAndForbidSuspendForDebuggerHolder
{
public:
DomainCacheCrstHolderForGCCoop(BaseDomain *pD)
: CrstAndForbidSuspendForDebuggerHolder(&pD->m_DomainCacheCrst)
{
WRAPPER_NO_CONTRACT;
}
};

class DomainLocalBlockLockHolder : public CrstHolder
{
public:
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/vm/crst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -789,8 +789,8 @@ CrstBase::CrstAndForbidSuspendForDebuggerHolder::CrstAndForbidSuspendForDebugger
// Reentrant locks are currently not supported
_ASSERTE((pCrst->m_dwFlags & CRST_REENTRANCY) == 0);

Thread *pThread = GetThread();
if (pThread->IsInForbidSuspendForDebuggerRegion())
Thread *pThread = GetThreadNULLOk();
if (pThread == nullptr || pThread->IsInForbidSuspendForDebuggerRegion())
{
AcquireLock(pCrst);
return;
Expand Down