public Task <IAsyncReaderWriterLockToken> WriterLockAsync(CancellationToken cancellationToken = default(CancellationToken), ReentrancyToken reentrancyToken = default(ReentrancyToken)) { TaskUtilities.AssertIsOnBackgroundThread(); var task = ReentrantOrCanceled(true, cancellationToken, reentrancyToken); if (task != null) { return(task); } var source = new LockSource(this, true); _queue.AddWriter(source, out var isFirstWriter); if (isFirstWriter) { source.Release(); } else { source.RegisterCancellation(cancellationToken); } return(source.Task); }
static AsyncReaderWriterLock() { LockTokenFactory = ReentrancyToken.CreateFactory <LockSource>(); }
private static Task <IAsyncReaderWriterLockToken> ReentrantOrCanceled(bool writerOnly, CancellationToken cancellationToken, ReentrancyToken reentrancyToken) { var source = LockTokenFactory.GetSource(reentrancyToken); if (source != null && source.TryReenter(writerOnly, out var task)) { return(task); } return(cancellationToken.IsCancellationRequested ? Task.FromCanceled <IAsyncReaderWriterLockToken>(cancellationToken) : null); }
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 Task <IAsyncReaderWriterLockToken> ReaderLockAsync(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); } var readerFromToken = ReaderLockTokenFactory.GetSource(reentrancyToken); if (readerFromToken != null && readerFromToken.TryReenter(out task)) { return(task); } while (true) { if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <IAsyncReaderWriterLockToken>(cancellationToken)); } task = _readerTail.WaitAsync(cancellationToken); if (task != null) { return(task); } } }
public Token(Action dispose, ReaderLockSource reentrancySource) { _dispose = dispose; Reentrancy = ReaderLockTokenFactory.Create(reentrancySource); }