Example #1
0
        /// <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));
            }
        }
Example #2
0
        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);
            }
        }
Example #3
0
        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));
        }
Example #4
0
        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);
        }
Example #5
0
        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));
        }