/// <summary> /// Allocates memory from the pipeline to write into. /// </summary> /// <param name="minimumSize">The minimum size buffer to allocate</param> /// <returns>A <see cref="WritableBuffer"/> that can be written to.</returns> WritableBuffer IPipeWriter.Alloc(int minimumSize) { if (_writerCompletion.IsCompleted) { PipelinesThrowHelper.ThrowInvalidOperationException(ExceptionResource.NoWritingAllowed, _writerCompletion.Location); } if (minimumSize < 0) { PipelinesThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.minimumSize); } lock (_sync) { // CompareExchange not required as its setting to current value if test fails _writingState.Begin(ExceptionResource.AlreadyWriting); if (minimumSize > 0) { try { AllocateWriteHeadUnsynchronized(minimumSize); } catch (Exception) { // Reset producing state if allocation failed _writingState.End(ExceptionResource.NoWriteToComplete); throw; } } _currentWriteLength = 0; return(new WritableBuffer(this)); } }
private void GetResult(ref ReadResult result) { if (_writerCompletion.IsCompletedOrThrow()) { result.ResultFlags |= ResultFlags.Completed; } var isCancelled = _readerAwaitable.ObserveCancelation(); if (isCancelled) { result.ResultFlags |= ResultFlags.Cancelled; } // No need to read end if there is no head var head = _readHead; if (head != null) { // Reading commit head shared with writer result.ResultBuffer = new ReadableBuffer(head, head.Start, _commitHead, _commitHeadIndex); } if (isCancelled) { _readingState.BeginTentative(ExceptionResource.AlreadyReading); } else { _readingState.Begin(ExceptionResource.AlreadyReading); } }
ReadResult IReadableBufferAwaiter.GetResult() { GetResult(ref _readerAwaitable, ref _writerCompletion, out bool isCancelled, out bool isCompleted); ReadableBuffer buffer; lock (_sync) { ReadCursor readEnd; // No need to read end if there is no head var head = _readHead; if (head == null) { readEnd = new ReadCursor(null); } else { // Reading commit head shared with writer readEnd = new ReadCursor(_commitHead, _commitHeadIndex); } _readingState.Begin(ExceptionResource.AlreadyReading); buffer = new ReadableBuffer(new ReadCursor(head), readEnd); } return(new ReadResult(buffer, isCancelled, isCompleted)); }
private void GetResult(ref ReadResult result) { if (_writerCompletion.IsCompletedOrThrow()) { result.ResultFlags |= ResultFlags.Completed; } if (_readerAwaitable.ObserveCancelation()) { result.ResultFlags |= ResultFlags.Cancelled; } // No need to read end if there is no head var head = _readHead; if (head != null) { // Reading commit head shared with writer result.ResultBuffer.BufferEnd.Segment = _commitHead; result.ResultBuffer.BufferEnd.Index = _commitHeadIndex; result.ResultBuffer.BufferLength = ReadCursor.GetLength(head, head.Start, _commitHead, _commitHeadIndex); result.ResultBuffer.BufferStart.Segment = head; result.ResultBuffer.BufferStart.Index = head.Start; } _readingState.Begin(ExceptionResource.AlreadyReading); }
private ReadableBuffer Read() { _readingState.Begin(ExceptionResource.AlreadyReading); ReadCursor readEnd; // No need to read end if there is no head var head = _readHead; if (head == null) { readEnd = new ReadCursor(null); } else { // Reading commit head shared with writer lock (_sync) { readEnd = new ReadCursor(_commitHead, _commitHeadIndex); } } return(new ReadableBuffer(new ReadCursor(head), readEnd)); }