/// <summary> /// Enter a critical section. /// </summary> /// <param name="obj">The object to use.</param> /// <returns>The disposable section holding the lock.</returns> public static IDisposable Enter(object obj) { bool isLockTaken = false; try { Monitor.Enter(obj, ref isLockTaken); // If we got this far shoud always be true. Debug.Assert(isLockTaken, "Lock is taken."); #if DEBUG lock (RgLocks) { if (HeldLocks == null) { HeldLocks = new Stack <LockInfo>(); } LockInfo lockInfo = FindLock(obj); LockInfo potentionDeadlock = null; foreach (LockInfo currentLock in HeldLocks) { // Recursive lock ok. if (currentLock == lockInfo) { potentionDeadlock = null; continue; } if (currentLock.IsDependent(lockInfo)) { potentionDeadlock = currentLock; } } Debug.Assert(potentionDeadlock == null, "Potention Deadlock"); bool isRec = lockInfo.OwningThread != -1; Debug.Assert(lockInfo.OwningThread == -1 || lockInfo.OwningThread == Thread.CurrentThread.ManagedThreadId, "Lock owned or managed thread does not own lock."); lockInfo.OwningThread = Thread.CurrentThread.ManagedThreadId; if (HeldLocks.Count != 0 && potentionDeadlock == null && !isRec) { lockInfo.AddDependent(HeldLocks.Peek()); } HeldLocks.Push(lockInfo); return(new ExitOnDispose(obj, lockInfo, isRec)); } #else return(new ExitOnDispose(obj)); #endif } catch { // If for some resons we messed up, release lock. if (isLockTaken) { Monitor.Exit(obj); } throw; } }