// Called by any thread to check the wait chain and deadlock state of another thread (or itself) private IList <WaitChainInfo> GetWaitChainI(Int32 targetThreadId) { // Initialize the wait chain result List <WaitChainInfo> waitChain = new List <WaitChainInfo>(); lock (m_syncLock) { // Walk the wait chain for (Int32 blockedThreadId = targetThreadId; true;) { // Determine if the thread in question is blocked and what it is blocked on. ThreadBlockInfo blockedThreadInfo = GetBlockedThreadInfo(blockedThreadId); // If the thread is not in a wait state, just return if (blockedThreadInfo == null) { return(waitChain); } // Do we know what thread this thread is blocked on? Int32 blockingThreadId = blockedThreadInfo.BlockingThreadId; if (blockingThreadId == 0) { // We don't know, try to detect it ThreadBlockInfo blockingThreadInfo = GetBlockingThreadInfo( blockedThreadInfo.BlockObject, blockedThreadInfo.AcquiredExclusively); if (blockingThreadInfo != null) { blockingThreadId = blockingThreadInfo.BlockedThreadId; } } // Add the thread that is currently blocked to the wait chain waitChain.Add(new WaitChainInfo(blockedThreadId, blockingThreadId, blockedThreadInfo.BlockObject)); // If no thread is blocking the blocked thread, there is no deadlock if (blockingThreadId == 0) { return(waitChain); } // If the owning thread is the original target thread, then we have a deadlock situation if (blockingThreadId == targetThreadId) { throw new Exception <DeadlockExceptionArgs>( new DeadlockExceptionArgs(waitChain), "Deadlock"); } // Traverse what this thread is blocked on... blockedThreadId = blockingThreadId; } } }
private void BlockThreadAndCheckDeadlock(ThreadBlockInfo tli) { try { Monitor.Enter(m_syncLock); m_BlockedThreads.Add(tli); Monitor.Exit(m_syncLock); // Check for deadlock (wait chain result is thrown away) GetWaitChainI(Thread.CurrentThread.ManagedThreadId); } catch { // If anything goes wrong (most-likely a DeadlockException), // cleanup by indicating that this thread did not block because it // will not acquire the lock UnblockI(false); throw; } }
private void BlockThreadAndCheckDeadlock(ThreadBlockInfo tli) { try { Monitor.Enter(m_syncLock); m_BlockedThreads.Add(tli); Monitor.Exit(m_syncLock); // Check for deadlock (wait chain result is thrown away) GetWaitChainI(Thread.CurrentThread.ManagedThreadId); } catch { // If anything goes wrong (most-likely a DeadlockException), // cleanup by indicating that this thread did not block because it // will not acquire the lock UnblockI(false); throw; } }