}
CONTRACTL_END;
- CrstHolder holder(&m_DomainCacheCrst);
+ GCX_PREEMP();
+ DomainCacheCrstHolderForGCCoop holder(this);
+
// !!! suppress exceptions
if(!m_AssemblyCache.StoreFile(pSpec, pFile) && !fAllowFailure)
{
}
CONTRACTL_END;
- CrstHolder holder(&m_DomainCacheCrst);
+ GCX_PREEMP();
+ DomainCacheCrstHolderForGCCoop holder(this);
+
// !!! suppress exceptions
BOOL bRetVal = m_AssemblyCache.StoreAssembly(pSpec, pAssembly);
return bRetVal;
if (ex->IsTransient())
return TRUE;
- CrstHolder holder(&m_DomainCacheCrst);
+ GCX_PREEMP();
+ DomainCacheCrstHolderForGCCoop holder(this);
+
// !!! suppress exceptions
return m_AssemblyCache.StoreException(pSpec, ex);
}
}
CONTRACTL_END;
- CrstHolder lock(&m_DomainCacheCrst);
+ DomainCacheCrstHolderForGCPreemp lock(this);
const UnmanagedImageCacheEntry *existingEntry = m_unmanagedCache.LookupPtr(libraryName);
if (existingEntry != NULL)
}
CONTRACT_END;
- CrstHolder lock(&m_DomainCacheCrst);
+ DomainCacheCrstHolderForGCPreemp lock(this);
+
const UnmanagedImageCacheEntry *existingEntry = m_unmanagedCache.LookupPtr(libraryName);
if (existingEntry == NULL)
RETURN NULL;
}
CONTRACTL_END;
- CrstHolder holder(&m_DomainCacheCrst);
+ GCX_PREEMP();
+ DomainCacheCrstHolderForGCCoop holder(this);
return m_AssemblyCache.RemoveAssembly(pAssembly);
}
};
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:
// 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;