void EnqueueFrameWithoutMerge(IHttp2RemoteFlowControlled frame) { _pendingWriteQueue.AddToBack(frame); // This must be called after adding to the queue in order so that hasFrame() is // updated before updating the stream state. IncrementPendingBytes(frame.Size, true); }
/// <summary> /// Discards this <see cref="IHttp2RemoteFlowControlled"/>, writing an error. If this frame is in the pending queue, /// the unwritten bytes are removed from this branch of the priority tree. /// </summary> /// <param name="frame"></param> /// <param name="cause"></param> void WriteError(IHttp2RemoteFlowControlled frame, Http2Exception cause) { IChannelHandlerContext ctx = _controller._ctx; Debug.Assert(ctx is object); DecrementPendingBytes(frame.Size, true); frame.Error(ctx, cause); }
public override bool Merge(IChannelHandlerContext ctx, IHttp2RemoteFlowControlled next) { if (!(next is FlowControlledData nextData) || (uint)Size > (uint)(int.MaxValue - nextData.Size)) { return(false); } nextData._queue.CopyTo(_queue); _dataSize = _queue.ReadableBytes(); // Given that we're merging data into a frame it doesn't really make sense to accumulate padding. _padding = Math.Max(_padding, nextData._padding); _endOfStream = nextData._endOfStream; return(true); }
public void AddFlowControlled(IHttp2Stream stream, IHttp2RemoteFlowControlled frame) { // The context can be null assuming the frame will be queued and send later when the context is set. Debug.Assert(_ctx is null || _ctx.Executor.InEventLoop); if (frame is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.frame); } try { _monitor.EnqueueFrame(GetState(stream), frame); } catch (Exception t) { frame.Error(_ctx, t); } }
/// <summary> /// Adds the <paramref name="frame"/> to the pending queue and increments the pending byte count. /// </summary> /// <param name="frame"></param> internal void EnqueueFrame(IHttp2RemoteFlowControlled frame) { var last = _pendingWriteQueue.LastOrDefault; if (last is null) { EnqueueFrameWithoutMerge(frame); return; } int lastSize = last.Size; if (last.Merge(_controller._ctx, frame)) { IncrementPendingBytes(last.Size - lastSize, true); return; } EnqueueFrameWithoutMerge(frame); }
protected internal override void EnqueueFrame(FlowState state, IHttp2RemoteFlowControlled frame) { base.EnqueueFrame(state, frame); CheckConnectionThenStreamWritabilityChanged(state); }
/// <summary> /// Add a frame to be sent via flow control. /// </summary> /// <param name="state">The state associated with the stream which the <paramref name="frame"/> is associated with.</param> /// <param name="frame">the frame to enqueue.</param> /// <remarks>If a writability error occurs.</remarks> protected internal virtual void EnqueueFrame(FlowState state, IHttp2RemoteFlowControlled frame) { state.EnqueueFrame(frame); }
public abstract bool Merge(IChannelHandlerContext ctx, IHttp2RemoteFlowControlled next);
public override bool Merge(IChannelHandlerContext ctx, IHttp2RemoteFlowControlled next) { return(false); }