internal WritableBufferAwaitable FlushAsync() { if (_producingState.IsActive) { // Commit the data as not already committed Commit(); } _readerAwaitable.Resume(); return(new WritableBufferAwaitable(this)); }
// Reading void IPipeReader.Advance(ReadCursor consumed, ReadCursor examined) { BufferSegment returnStart = null; BufferSegment returnEnd = null; int consumedBytes = 0; if (!consumed.IsDefault) { consumedBytes = ReadCursor.GetLength(_readHead, _readHead.Start, consumed.Segment, consumed.Index); returnStart = _readHead; returnEnd = consumed.Segment; _readHead = consumed.Segment; _readHead.Start = consumed.Index; } // Reading commit head shared with writer bool consumedEverything; long currentLength; lock (_sync) { currentLength = (_length -= consumedBytes); consumedEverything = examined.Segment == _commitHead && examined.Index == _commitHeadIndex && !_writerCompletion.IsCompleted; } // We reset the awaitable to not completed if we've consumed everything the producer produced so far if (consumedEverything) { _readerAwaitable.Reset(); } while (returnStart != null && returnStart != returnEnd) { var returnSegment = returnStart; returnStart = returnStart.Next; returnSegment.Dispose(); } // CompareExchange not required as its setting to current value if test fails _consumingState.End(ExceptionResource.NotConsumingToComplete); if (currentLength < _maximumSizeLow) { _writerAwaitable.Resume(); } }