private void PushLevel(bool permitIntraLevel) { Stack <LeveledLock> currentLevelStack; try { currentLevelStack = Thread.GetData(LockLevelTlsSlot) as Stack <LeveledLock>; } catch (Exception) { return; } if (currentLevelStack is null) { // We've never accessed the TLS data yet; construct a new Stack for our levels // and stash it away in TLS. currentLevelStack = new Stack <LeveledLock>(); Thread.SetData(LockLevelTlsSlot, currentLevelStack); } else if (currentLevelStack.Count > 0) { // If the stack in TLS already recorded a lock, validate that we are not violating // the locking protocol. A violation occurs when our lock is higher level than the // current lock, or equal to the level (when the reentrant bit has not been set on // at least one of the locks involved). LeveledLock currentLock = currentLevelStack.Peek(); int currentLevel = currentLock._level; if (_level > currentLevel || (ReferenceEquals(currentLock, this) && !_reentrant) || (!ReferenceEquals(currentLock, this) && _level == currentLevel && !permitIntraLevel)) { throw new LockLevelException(currentLock, this); } } // If we reached here, we are OK to proceed with locking. Stash the current level in TLS. currentLevelStack.Push(this); }
public LockLevelException(LeveledLock currentLock, LeveledLock newLock) : base(string.Format("You attempted to violate the locking protocol by acquiring lock {0} " + "while the thread already owns lock {1}.", newLock, currentLock)) { }
internal LeveledLockCookie(LeveledLock lck) { _lck = lck; }