public AsyncReaderWriterLock() { _readerTail = new ReaderLockSource(this); _writerTail = new WriterLockSource(this); _readerTail.CompleteTasks(); _writerTail.TryCompleteTask(); _writerTail.Task.Result.Dispose(); }
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); }
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(); } }
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(); } }
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); } }
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); } }
public Token(Action dispose, WriterLockSource reentrancySource) { _dispose = dispose; Reentrancy = WriterLockTokenFactory.Create(reentrancySource); }