/// <summary> /// Adds a reader from exclusive reader lock /// </summary> /// <remarks> /// 1. _wTail erlTail /// ↓ ↓ /// R−→R−→R ―► R−→R−→R−→E /// ↑ ↑ /// _tail _tail /// /// /// 2. _wTail _wTail erlTail /// ↓ ↓ ↓ /// R−→R−→W ―► R−→R−→W−→E /// ↑ ↑ /// _tail _tail /// /// /// 3. _wTail _wTail erlTail /// ↓ ↓ ↓ /// R−→W−→W−→R−→R ―► R−→W−→W−→R−→R−→E /// ↑ ↑ /// _tail _tail /// /// /// 4. _wTail _tail _wTail _tail /// ↓ ↓ ↓ ↓ /// R−→W−→W−→E−→R ―► R−→W−→W−→E−→E−→R /// ↑ ↑ /// erlTail erlTail /// </remarks> public void AddExclusiveReader(ExclusiveReaderLockSource item, out bool isAddedAfterWriterOrExclusiveReader) { lock (this) { var erlTail = item.ExclusiveReaderLock.Tail; if (erlTail?.Next == null) { UpdateTail(item); isAddedAfterWriterOrExclusiveReader = _wTail != null || erlTail != null; } else { Link(item, erlTail.Next); Link(erlTail, item); isAddedAfterWriterOrExclusiveReader = true; } Interlocked.Exchange(ref item.ExclusiveReaderLock.Tail, item); } }
/// <summary> /// Adds a reader from exclusive reader lock /// </summary> /// <remarks> /// 1. _wTail erlTail /// ↓ ↓ /// R−→R−→R ―► R−→R−→R−→E /// ↑ ↑ /// _tail _tail /// /// /// 2. _wTail _wTail erlTail /// ↓ ↓ ↓ /// R−→R−→W ―► R−→R−→W−→E /// ↑ ↑ /// _tail _tail /// /// /// 3. _wTail _wTail erlTail /// ↓ ↓ ↓ /// R−→W−→W−→R−→R ―► R−→W−→W−→R−→R−→E /// ↑ ↑ /// _tail _tail /// /// /// 4. _wTail _tail _wTail _tail /// ↓ ↓ ↓ ↓ /// R−→W−→W−→E−→R ―► R−→W−→W−→E−→E−→R /// ↑ ↑ /// erlTail erlTail /// </remarks> public void AddExclusiveReader(ExclusiveReaderLockSource item, out bool isAddedAfterWriterOrExclusiveReader) { lock (this) { var erlTail = item.ExclusiveReaderLock.Tail; if (erlTail?.Next == null) { UpdateTail(item); isAddedAfterWriterOrExclusiveReader = _wTail != null || erlTail != null; } else { Link(item, erlTail.Next); Link(erlTail, item); isAddedAfterWriterOrExclusiveReader = true; } Interlocked.Exchange(ref item.ExclusiveReaderLock.Tail, item); } }
private Task <IAsyncReaderWriterLockToken> ExclusiveReaderLockAsync(ExclusiveReaderLock erLock, CancellationToken cancellationToken = default(CancellationToken)) { TaskUtilities.AssertIsOnBackgroundThread(); if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <IAsyncReaderWriterLockToken>(cancellationToken)); } var source = new ExclusiveReaderLockSource(this, erLock); _queue.AddExclusiveReader(source, out var isAddedAfterWriterOrExclusiveReader); if (isAddedAfterWriterOrExclusiveReader) { source.RegisterCancellation(cancellationToken); } else { source.Release(); } return(source.Task); }