/// <summary> /// Acquires the reader lock. /// </summary> /// <param name="timeout">The timeout.</param> public void AcquireReaderLock(long timeout) { var timeCur = DateTimeHelper.CurrentTimeMillis; var timeEnd = timeCur + timeout; var ii = 0; for (;;) { var result = WithMainLock( timeCur, timeEnd, () => { if ((_uLockFlags == LockFlags.None) || (_uLockFlags == LockFlags.Shared)) { _uSharedCount++; return(true); } return(false); }); if (result) { return; } SlimLock.SmartWait(++ii); timeCur = DateTimeHelper.CurrentTimeMillis; } }
/// <summary> /// Acquires the writer lock. /// </summary> /// <param name="timeout">The timeout.</param> public void AcquireWriterLock(long timeout) { var timeCur = DateTimeHelper.CurrentTimeMillis; var timeEnd = timeCur + timeout; var ii = 0; var upgrade = new bool[] { false }; try { for (;;) { var result = WithMainLock( timeCur, timeEnd, () => { if (_uLockFlags == LockFlags.None) { _uLockFlags = LockFlags.Exclusive; _uLockOwner = System.Threading.Thread.CurrentThread.ManagedThreadId; return(true); } else if (_uLockFlags == LockFlags.Shared) { _uLockFlags |= LockFlags.ExclusiveUpgrade; upgrade[0] = true; return(false); } else if (_uLockFlags == LockFlags.ExclusiveUpgrade) { // shared flag has been cleared upgrade[0] = false; _uLockFlags = LockFlags.Exclusive; _uLockOwner = System.Threading.Thread.CurrentThread.ManagedThreadId; return(true); } // Exclusive - wait return(false); }); if (result) { return; } SlimLock.SmartWait(++ii); timeCur = DateTimeHelper.CurrentTimeMillis; } } finally { if (upgrade[0]) { WithMainLock(() => _uLockFlags &= ~LockFlags.ExclusiveUpgrade); } } }
/// <summary> /// Acquires the reader lock. /// </summary> /// <param name="timeout">The timeout.</param> public Node AcquireReaderLock(long timeout) { var timeCur = DateTimeHelper.CurrentTimeMillis; var timeEnd = timeCur + timeout; var curr = _rnode; var node = PushNode(new Node(NodeFlags.Shared)); var iter = 0; for ( ;;) { #if STATISTICS node.Iterations++; #endif if (curr == node) { #if STATISTICS node.TimeAcquire = PerformanceObserver.MicroTime; #endif return(_rnode = node); } else if (curr.Flags == NodeFlags.Shared) { curr = curr.Next; #if STATISTICS node.ChainLength++; #endif } else if (curr.Flags == NodeFlags.Exclusive) { SlimLock.SmartWait(++iter); } else if (curr.Flags == NodeFlags.None) { curr = curr.Next; // dead node #if STATISTICS node.ChainLength++; #endif } else { throw new IllegalStateException(); } } }