private void PushLevel(bool permitIntraLevel) { Stack <LeveledLock> currentLevelStack = Thread.GetData(lockLevelTlsSlot) as Stack <LeveledLock>; if (currentLevelStack == 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 || (currentLock == this && !_reentrant) || (_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}.", currentLock, newLock)) { }
// Constructor internal LeveledLockCookie(LeveledLock lck) { this._lck = lck; }