示例#1
0
        /// <inheritdoc/>
        public virtual void PartialFree(int newCount, ref ChannelWriterBufferSlice <T> writeSlice)
        {
            if (newCount != 1)
            {
                throw new ArgumentOutOfRangeException(
                          "newCount should be less or equal than current and greater than zero.",
                          nameof(newCount));
            }

            // Do nothing.
        }
示例#2
0
        /// <inheritdoc/>
        public virtual void CompleteWrite(int processedCount, ref ChannelWriterBufferSlice <T> writeSlice)
        {
            if ((processedCount < 0) || (processedCount > 1))
            {
                throw new ArgumentOutOfRangeException(
                          "processedCount should be greater or equal to zero and less than slice length.",
                          nameof(processedCount));
            }

            if (processedCount == 1)
            {
                WriteAsync(writeSlice.Span[0]).GetAwaiter().GetResult();
            }
        }
示例#3
0
            /// <inheritdoc/>
            public void CompleteWrite(int processedCount, ref ChannelWriterBufferSlice <T> writeSlice)
            {
                if ((processedCount < 0) || (processedCount > writeSlice.Length))
                {
                    throw new ArgumentOutOfRangeException(
                              nameof(processedCount),
                              "processedCount should be non-negative and less than allocated count");
                }

                using (var guard = new StateWriteGuard <TSyncObject>(_syncObject, _owner))
                {
                    if (!_owner._idToSliceEntries.TryGetValue(writeSlice.Id, out var sliceEntryNode))
                    {
                        throw new ArgumentException("Wrong slice variable.");
                    }

                    if (!_writeInProgress)
                    {
                        throw new InvalidOperationException("CompleteWrite operation has not been started.");
                    }

                    var sliceEntry = sliceEntryNode.Value;
                    if (writeSlice.Length != sliceEntry.Length)
                    {
                        throw new ArgumentException("The provided slice have an invalid state", nameof(writeSlice));
                    }

                    guard.NotifyWritten(processedCount, sliceEntry.Length);

                    sliceEntry.Status = SliceEntryStatus.Data;

                    if (processedCount == 0)
                    {
                        _owner.RemoveNode(sliceEntryNode);
                    }
                    else
                    {
                        sliceEntry.Length = processedCount;
                    }

                    _writeInProgress = false;
                }
            }
示例#4
0
            /// <inheritdoc/>
            public void PartialFree(int newCount, ref ChannelWriterBufferSlice <T> writeSlice)
            {
                if ((newCount < 1) || (newCount > writeSlice.Length))
                {
                    throw new ArgumentOutOfRangeException(
                              nameof(newCount),
                              "New count should be greater than zero and less or equal to already allocated length.");
                }

                using (var guard = new StateWriteGuard <TSyncObject>(_syncObject, _owner))
                {
                    if (!_owner._idToSliceEntries.TryGetValue(writeSlice.Id, out var sliceEntryNode))
                    {
                        throw new ArgumentException("Wrong slice variable.");
                    }

                    if (!_writeInProgress)
                    {
                        throw new InvalidOperationException("PartialFree operation has not been started.");
                    }

                    if (writeSlice.Length != sliceEntryNode.Value.Length)
                    {
                        throw new ArgumentException("The provided slice have an invalid state", nameof(writeSlice));
                    }

                    int decreaseSize = sliceEntryNode.Value.Length - newCount;

                    if (decreaseSize == 0)
                    {
                        // shit in shit out
                        return;
                    }

                    writeSlice.DecreaseLength(decreaseSize);

                    sliceEntryNode.Value.Length = newCount;

                    guard.NotifyWritten(0, decreaseSize);
                }
            }
 void IChannelWriter <T> .PartialFree(int newCount, ref ChannelWriterBufferSlice <T> writeSlice) =>
 throw new NotSupportedException();
 void IChannelWriter <T> .CompleteWrite(int processedCount, ref ChannelWriterBufferSlice <T> writeSlice) =>
 throw new NotSupportedException();
示例#7
0
 /// <inheritdoc/>
 public void PartialFree(int newCount, ref ChannelWriterBufferSlice <T> writeSlice) =>
 throw new NotImplementedException();
示例#8
0
 /// <inheritdoc/>
 public void CompleteWrite(int processedCount, ref ChannelWriterBufferSlice <T> writeSlice) =>
 throw new NotImplementedException();
示例#9
0
            /// <inheritdoc/>
            public async ValueTask <ChannelWriterBufferSlice <T> > StartWriteAsync(
                int count,
                CancellationToken cancellationToken)
            {
                if (count <= 0)
                {
                    throw new ArgumentOutOfRangeException(nameof(count), "Count should be non-zero positive value.");
                }

                bool isWriteStarted = false;

                while (true)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    Task <VoidResult> taskToAwait;

                    using (var guard = new StateWriteGuard <TSyncObject>(_syncObject, _owner))
                    {
                        if (!isWriteStarted)
                        {
                            EnsureSequentialUsage();
                            _writeInProgress = true;
                            isWriteStarted   = true;
                        }

                        if (_owner._isCompleted)
                        {
                            _writeInProgress = false;
                            throw new ChannelClosedException();
                        }

                        int freeSpace = guard.GetFreeSpaceForWrite();
                        if (freeSpace != 0)
                        {
                            int amountToAllocate = Math.Min(Math.Min(count, freeSpace), _owner._maxSliceLength);

                            guard.NotifyAllocated(amountToAllocate);

                            var sliceEntry = _owner.AllocateNewEntry();
                            sliceEntry.Status = SliceEntryStatus.AllocatedForWrite;
                            sliceEntry.Length = amountToAllocate;

                            var slice = new ChannelWriterBufferSlice <T>(
                                sliceEntry.Buffer,
                                0,
                                amountToAllocate,
                                sliceEntry.Id);
                            return(slice);
                        }

                        Debug.Assert(_owner._writeSpaceAvailableCs != null, "_owner._writeSpaceAvailableCs != null");
                        taskToAwait = _owner._writeSpaceAvailableCs.Task;
                    }

                    await taskToAwait.WithCancellation(cancellationToken);

                    // TODO: put this to avoid possible recursion.
                    // await Task.Yield();
                }
            }