summaryrefslogtreecommitdiff
path: root/src/vm/pendingload.h
diff options
context:
space:
mode:
authorRahul Kumar <rahku@microsoft.com>2016-08-12 16:47:47 -0700
committerRahul Kumar <rahku@microsoft.com>2016-08-12 16:51:20 -0700
commit479485f3f44172e82e5c2f3eb1aba389072df325 (patch)
tree12f0ada19833bdd7bc691cda827a395cc32db475 /src/vm/pendingload.h
parent99d29f3284cdc84df69e1c0a91cba72419751956 (diff)
downloadcoreclr-479485f3f44172e82e5c2f3eb1aba389072df325.tar.gz
coreclr-479485f3f44172e82e5c2f3eb1aba389072df325.tar.bz2
coreclr-479485f3f44172e82e5c2f3eb1aba389072df325.zip
Issue: If two threads try to load the same type it can cause clr to hang if the first thread to start the load happens to be a background thread. Background thread would create PendingTypeLoadEntry and insert it into unresolvedClassHash. Second thread (having normal priority) would block on PendingTypeLoadEntry->m_crst waiting for the background thread to unblock it. After doing partial load of type background thread periodically checks if there are other threads waiting for type to get loaded. In this case it does find a thread waiting so it unblocks thread. However, background thread has not removed PendingTypeLoadEntry from unresolvedClassHash. This causes the second thread to continue spinning and so not allowing background thread to get any processor cycles to remove PendingTypeLoadEntry from unresolvedClassHash. This cause app to be seem like it has hung. It is possible that this may not repro on multi-proc machine where the background thread can get scheduled on another processor when second thread continues to spin on another processor.
Fix: First remove the PendingTypeLoadEntry from unresolvedClassHash and then unblock the waiting threads.
Diffstat (limited to 'src/vm/pendingload.h')
-rw-r--r--src/vm/pendingload.h15
1 files changed, 11 insertions, 4 deletions
diff --git a/src/vm/pendingload.h b/src/vm/pendingload.h
index 72cb415f3a..1373215d0a 100644
--- a/src/vm/pendingload.h
+++ b/src/vm/pendingload.h
@@ -135,10 +135,6 @@ public:
m_pException=NULL;
}
EX_END_CATCH(SwallowAllExceptions);
-
- _ASSERTE(m_fLockAcquired);
- m_Crst.Leave();
- m_fLockAcquired = FALSE;
}
void SetResult(TypeHandle typeHnd)
@@ -153,6 +149,17 @@ public:
CONTRACTL_END;
m_typeHandle = typeHnd;
+ }
+
+ void UnblockWaiters()
+ {
+ CONTRACTL
+ {
+ NOTHROW;
+ PRECONDITION(HasLock());
+ PRECONDITION(m_dwWaitCount > 0);
+ }
+ CONTRACTL_END;
_ASSERTE(m_fLockAcquired);
m_Crst.Leave();