コード例 #1
0
        private void AllocateMemory(int sizeHint)
        {
            if (_head == null)
            {
                // We need to allocate memory to write since nobody has written before
                BufferSegment newSegment = AllocateSegment(sizeHint);

                // Set all the pointers
                _head = _tail = newSegment;
                _tailBytesBuffered = 0;
            }
            else
            {
                int bytesLeftInBuffer = _tailMemory.Length;

                if (bytesLeftInBuffer == 0 || bytesLeftInBuffer < sizeHint)
                {
                    if (_tailBytesBuffered > 0)
                    {
                        // Flush buffered data to the segment
                        _tail.End         += _tailBytesBuffered;
                        _tailBytesBuffered = 0;
                    }

                    BufferSegment newSegment = AllocateSegment(sizeHint);

                    _tail.SetNext(newSegment);
                    _tail = newSegment;
                }
            }
        }
コード例 #2
0
        private void AllocateWriteHeadUnsynchronized(int sizeHint)
        {
            _operationState.BeginWrite();
            if (_writingHead == null)
            {
                // We need to allocate memory to write since nobody has written before
                BufferSegment newSegment = CreateSegmentUnsynchronized();
                newSegment.SetMemory(_pool.Rent(GetSegmentSize(sizeHint)));

                // Set all the pointers
                _writingHead = _readHead = _readTail = newSegment;
            }
            else
            {
                int bytesLeftInBuffer = _writingHead.WritableBytes;

                if (bytesLeftInBuffer == 0 || bytesLeftInBuffer < sizeHint)
                {
                    BufferSegment newSegment = CreateSegmentUnsynchronized();
                    newSegment.SetMemory(_pool.Rent(GetSegmentSize(sizeHint)));

                    _writingHead.SetNext(newSegment);
                    _writingHead = newSegment;
                }
            }
        }
コード例 #3
0
ファイル: Pipe.cs プロジェクト: saketmodi/corefx
        internal Memory <byte> GetMemory(int minimumSize)
        {
            if (_writerCompletion.IsCompleted)
            {
                ThrowHelper.ThrowInvalidOperationException_NoWritingAllowed();
            }

            if (minimumSize < 0)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.minimumSize);
            }

            lock (_sync)
            {
                BufferSegment segment = _writingHead ?? AllocateWriteHeadUnsynchronized(minimumSize);

                int bytesLeftInBuffer = segment.WritableBytes;

                // If inadequate bytes left or if the segment is readonly
                if (bytesLeftInBuffer == 0 || bytesLeftInBuffer < minimumSize || segment.ReadOnly)
                {
                    BufferSegment nextSegment = CreateSegmentUnsynchronized();

                    nextSegment.SetMemory(_pool.Rent(Math.Max(_minimumSegmentSize, minimumSize)));

                    segment.SetNext(nextSegment);

                    _writingHead = nextSegment;
                }
            }

            return(_writingHead.AvailableMemory.Slice(_writingHead.End, _writingHead.WritableBytes));
        }
コード例 #4
0
        private void AllocateWriteHeadSynchronized(int sizeHint)
        {
            lock (_sync)
            {
                _operationState.BeginWrite();

                if (_writingHead == null)
                {
                    // We need to allocate memory to write since nobody has written before
                    BufferSegment newSegment = AllocateSegment(sizeHint);

                    // Set all the pointers
                    _writingHead = _readHead = _readTail = _lastExamined = newSegment;
                }
                else
                {
                    int bytesLeftInBuffer = _writingMemory.Length;

                    if (bytesLeftInBuffer == 0 || bytesLeftInBuffer < sizeHint)
                    {
                        if (_buffered > 0)
                        {
                            // Flush buffered data to the segment
                            _writingHead.End += _buffered;
                            _buffered         = 0;
                        }

                        BufferSegment newSegment = AllocateSegment(sizeHint);

                        _writingHead.SetNext(newSegment);
                        _writingHead = newSegment;
                    }
                }
            }
        }
コード例 #5
0
        private void AllocateWriteHeadUnsynchronized(int sizeHint)
        {
            BufferSegment segment = null;

            if (_writingHead != null)
            {
                segment = _writingHead;

                int bytesLeftInBuffer = segment.WritableBytes;

                // If inadequate bytes left or if the segment is readonly
                if (bytesLeftInBuffer == 0 || bytesLeftInBuffer < sizeHint || segment.ReadOnly)
                {
                    BufferSegment nextSegment = CreateSegmentUnsynchronized();
                    nextSegment.SetMemory(_pool.Rent(GetSegmentSize(sizeHint)));

                    segment.SetNext(nextSegment);

                    _writingHead = nextSegment;
                }
            }
            else
            {
                if (_commitHead != null && !_commitHead.ReadOnly)
                {
                    // Try to return the tail so the calling code can append to it
                    int remaining = _commitHead.WritableBytes;

                    if (sizeHint <= remaining && remaining > 0)
                    {
                        // Free tail space of the right amount, use that
                        segment = _commitHead;

                        // Set write head to assigned segment
                        _writingHead = segment;
                        return;
                    }
                }

                // No free tail space, allocate a new segment
                segment = CreateSegmentUnsynchronized();
                segment.SetMemory(_pool.Rent(GetSegmentSize(sizeHint)));

                if (_commitHead == null)
                {
                    // No previous writes have occurred
                    _commitHead = segment;
                }
                else if (segment != _commitHead && _commitHead.Next == null)
                {
                    // Append the segment to the commit head if writes have been committed
                    // and it isn't the same segment (unused tail space)
                    _commitHead.SetNext(segment);
                }

                // Set write head to assigned segment
                _writingHead = segment;
            }
        }
コード例 #6
0
        private void CreateNewTailSegment()
        {
            var nextSegment = CreateBufferSegment();

            nextSegment.SetMemory(_pool.Rent(GetSegmentSize()));
            _readTail.SetNext(nextSegment);
            _readTail = nextSegment;
        }
コード例 #7
0
ファイル: Pipe.cs プロジェクト: WinCPP/corefxlab
        private BufferSegment AllocateWriteHeadUnsynchronized(int count)
        {
            BufferSegment segment = null;

            if (_commitHead != null && !_commitHead.ReadOnly)
            {
                // Try to return the tail so the calling code can append to it
                int remaining = _commitHead.WritableBytes;

                if (count <= remaining)
                {
                    // Free tail space of the right amount, use that
                    segment = _commitHead;
                }
            }

            if (segment == null)
            {
                // No free tail space, allocate a new segment
                segment = CreateSegmentUnsynchronized();
                segment.SetMemory(_pool.Rent(count));
            }

            if (_commitHead == null)
            {
                // No previous writes have occurred
                _commitHead = segment;
            }
            else if (segment != _commitHead && _commitHead.Next == null)
            {
                // Append the segment to the commit head if writes have been committed
                // and it isn't the same segment (unused tail space)
                _commitHead.SetNext(segment);
            }

            // Set write head to assigned segment
            _writingHead = segment;

            return(segment);
        }
コード例 #8
0
ファイル: Pipe.cs プロジェクト: jkotas/corefxlab
        internal void Append(ReadableBuffer buffer)
        {
            if (buffer.IsEmpty)
            {
                return; // nothing to do
            }

            EnsureAlloc();

            BufferSegment clonedEnd;
            var           clonedBegin = BufferSegment.Clone(buffer.Start, buffer.End, out clonedEnd);

            if (_writingHead == null)
            {
                // No active write
                lock (_sync)
                {
                    if (_commitHead == null)
                    {
                        // No allocated buffers yet, not locking as _readHead will be null
                        _commitHead = clonedBegin;
                    }
                    else
                    {
                        Debug.Assert(_commitHead.Next == null);
                        // Allocated buffer, append as next segment
                        _commitHead.SetNext(clonedBegin);
                    }
                }
            }
            else
            {
                Debug.Assert(_writingHead.Next == null);
                // Active write, append as next segment
                _writingHead.SetNext(clonedBegin);
            }

            // Move write head to end of buffer
            _writingHead         = clonedEnd;
            _currentWriteLength += buffer.Length;
        }
コード例 #9
0
ファイル: Pipe.cs プロジェクト: leafcxy/corefx
        internal Memory <byte> GetMemory(int sizeHint)
        {
            if (_writerCompletion.IsCompleted)
            {
                ThrowHelper.ThrowInvalidOperationException_NoWritingAllowed();
            }

            if (sizeHint < 0)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.minimumSize);
            }

            lock (_sync)
            {
                BufferSegment segment = _writingHead ?? AllocateWriteHeadUnsynchronized(sizeHint);

                int bytesLeftInBuffer = segment.WritableBytes;

                // If inadequate bytes left or if the segment is readonly
                if (bytesLeftInBuffer == 0 || bytesLeftInBuffer < sizeHint || segment.ReadOnly)
                {
                    BufferSegment nextSegment = CreateSegmentUnsynchronized();
                    nextSegment.SetMemory(_pool.Rent(GetSegmentSize(sizeHint)));

                    segment.SetNext(nextSegment);

                    _writingHead = nextSegment;
                }
            }

            // Slice the AvailableMemory to the WritableBytes size
            int           end             = _writingHead.End;
            Memory <byte> availableMemory = _writingHead.AvailableMemory;

            availableMemory = availableMemory.Slice(end, availableMemory.Length - end);
            return(availableMemory);
        }