Esempio n. 1
0
        public AsyncReaderWriterLock()
        {
            _readerTail = new ReaderLockSource(this);
            _writerTail = new WriterLockSource(this);

            _readerTail.CompleteTasks();
            _writerTail.TryCompleteTask();
            _writerTail.Task.Result.Dispose();
        }
Esempio n. 2
0
            public bool TrySetNext(out WriterLockSource next)
            {
                if (_nextWriter != null)
                {
                    next = null;
                    return(false);
                }

                next = new WriterLockSource(_host);
                return(Interlocked.CompareExchange(ref _nextWriter, next, null) == null);
            }
Esempio n. 3
0
        private void CompleteReaderTasksIfRequired(WriterLockSource writer)
        {
            var reader = _readerTail;

            while (writer != null && writer.IsCompleted)
            {
                writer = writer.NextWriter;
            }

            // No writer source left - complete reader source tasks
            if (writer == null)
            {
                reader.CompleteTasks();
            }
        }
Esempio n. 4
0
        private void CompleteNextTask(WriterLockSource writer)
        {
            var reader = _readerTail;

            while (writer != null && !writer.TryCompleteTask())
            {
                writer = writer.NextWriter;
            }

            // No writer source left - complete reader source tasks
            if (writer == null)
            {
                reader.CompleteTasks();
            }
        }
Esempio n. 5
0
        public Task <IAsyncReaderWriterLockToken> WriterLockAsync(CancellationToken cancellationToken = default(CancellationToken), ReentrancyToken reentrancyToken = default(ReentrancyToken))
        {
            Task <IAsyncReaderWriterLockToken> task;
            var writerFromToken = WriterLockTokenFactory.GetSource(reentrancyToken);

            if (writerFromToken != null && writerFromToken.TryReenter(out task))
            {
                return(task);
            }

            while (true)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(Task.FromCanceled <IAsyncReaderWriterLockToken>(cancellationToken));
                }

                WriterLockSource oldWriter = _writerTail;
                WriterLockSource newWriter;
                if (!oldWriter.TrySetNext(out newWriter))
                {
                    continue;
                }

                var reader = oldWriter.IsCompleted && _lastAcquiredWriter == oldWriter
                    ? Interlocked.Exchange(ref _readerTail, new ReaderLockSource(this))
                    : null;

                if (Interlocked.CompareExchange(ref _writerTail, newWriter, oldWriter) != oldWriter)
                {
                    throw new InvalidOperationException();
                }

                if (reader != null)   // oldWriter.IsCompleted
                {
                    reader.RegisterWait(newWriter, cancellationToken);
                }
                else
                {
                    oldWriter.RegisterWait(cancellationToken);
                }

                return(newWriter.Task);
            }
        }
Esempio n. 6
0
            public void RegisterWait(WriterLockSource writer, CancellationToken cancellationToken)
            {
                Interlocked.Exchange(ref _writer, writer);

                CompleteTasks();

                if (cancellationToken.IsCancellationRequested)
                {
                    CancelWaitReaders(cancellationToken);
                }
                else if (_count == 0)
                {
                    writer.TryCompleteTask();
                }
                else if (cancellationToken.CanBeCanceled)
                {
                    cancellationToken.Register(CancelWaitReaders, cancellationToken, false);
                }
            }
Esempio n. 7
0
 public Token(Action dispose, WriterLockSource reentrancySource)
 {
     _dispose   = dispose;
     Reentrancy = WriterLockTokenFactory.Create(reentrancySource);
 }