private Task <bool> WaitToWriteAsync(CancellationToken cancellationToken = default(CancellationToken)) { if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <bool>(cancellationToken)); } lock (SyncObj) { AssertInvariants(); // If we're done writing, no writes will ever succeed. if (_doneWriting != null) { return(ChannelUtilities.FalseTask); } // If there's space to write, a write is possible. // And if the mode involves dropping, we can always write, as even if it's // full we'll just drop an element to make room. if (_items.Count < _bufferedCapacity || _mode != BoundedChannelFullMode.Wait) { return(ChannelUtilities.TrueTask); } // We're still allowed to write, but there's no space, so ensure a waiter is queued and return it. return(ChannelUtilities.GetOrCreateWaiter(ref _waitingWriters, true, cancellationToken)); } }
private Task <bool> WaitToReadAsync(CancellationToken cancellationToken = default(CancellationToken)) { if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <bool>(cancellationToken)); } lock (SyncObj) { AssertInvariants(); // If there are any items available, a read is possible. if (!_items.IsEmpty) { return(ChannelUtilities.TrueTask); } // There were no items available, so if we're done writing, a read will never be possible. if (_doneWriting != null) { return(ChannelUtilities.FalseTask); } // There were no items available, but there could be in the future, so ensure // there's a blocked reader task and return it. return(ChannelUtilities.GetOrCreateWaiter(ref _waitingReaders, _runContinuationsAsynchronously, cancellationToken)); } }
private Task <bool> WaitToWriteAsync(CancellationToken cancellationToken = default(CancellationToken)) { lock (SyncObj) { // If we're done writing, fail. if (_completion.Task.IsCompleted) { return(ChannelUtilities.FalseTask); } // If there's a blocked reader, we can write if (!_blockedReaders.IsEmpty) { return(ChannelUtilities.TrueTask); } // Otherwise, queue the writer return(ChannelUtilities.GetOrCreateWaiter(ref _waitingWriters, true, cancellationToken)); } }
private Task <bool> WaitToReadAsync(CancellationToken cancellationToken = default(CancellationToken)) { lock (SyncObj) { // If we're done writing, fail. if (_completion.Task.IsCompleted) { return(_completion.Task.IsFaulted ? Task.FromException <bool>(_completion.Task.Exception.InnerException) : ChannelUtilities.FalseTask); } // If there's a blocked writer, we can read. if (!_blockedWriters.IsEmpty) { return(ChannelUtilities.TrueTask); } // Otherwise, queue the waiter. return(ChannelUtilities.GetOrCreateWaiter(ref _waitingReaders, true, cancellationToken)); } }