/// <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);
                }
            }
Beispiel #2
0
            /// <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);
                }
            }
Beispiel #3
0
        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);
        }