public WeightedFairQueueByteDistributor(IHttp2Connection connection, int maxStateOnlySize)
        {
            uint uMaxStateOnlySize = (uint)maxStateOnlySize;

            if (uMaxStateOnlySize > SharedConstants.TooBigOrNegative)
            {
                ThrowHelper.ThrowArgumentException_PositiveOrZero(maxStateOnlySize, ExceptionArgument.maxStateOnlySize);
            }
            if (0u >= uMaxStateOnlySize)
            {
                _stateOnlyMap          = EmptyDictionary <int, State> .Instance;
                _stateOnlyRemovalQueue = EmptyPriorityQueue <State> .Instance;
            }
            else
            {
                _stateOnlyMap = new Dictionary <int, State>(maxStateOnlySize);
                // +2 because we may exceed the limit by 2 if a new dependency has no associated IHttp2Stream object. We need
                // to create the State objects to put them into the dependency tree, which then impacts priority.
                _stateOnlyRemovalQueue = new PriorityQueue <State>(StateOnlyComparator.Instance, maxStateOnlySize + 2);
            }

            _maxStateOnlySize = maxStateOnlySize;

            _connection = connection;
            _stateKey   = connection.NewKey();
            IHttp2Stream connectionStream = connection.ConnectionStream;

            _ = connectionStream.SetProperty(_stateKey, _connectionState = new State(this, connectionStream, 16));

            // Register for notification of new streams.
            connection.AddListener(this);
        }
 public DefaultHttp2FrameStream SetStreamAndProperty(IHttp2ConnectionPropertyKey streamKey, IHttp2Stream stream)
 {
     Debug.Assert(v_id == -1 || stream.Id == v_id);
     _ = stream.SetProperty(streamKey, this);
     InternalStream = stream;
     return(this);
 }
        public override void OnStreamAdded(IHttp2Stream stream)
        {
            int streamId = stream.Id;

            if (!_stateOnlyMap.TryGetValue(streamId, out State state))
            {
                state = new State(this, stream);
                // Only the stream which was just added will change parents. So we only need an array of size 1.
                List <ParentChangedEvent> events = new List <ParentChangedEvent>(1);
                _connectionState.TakeChild(state, false, events);
                NotifyParentChanged(events);
            }
            else
            {
                _             = _stateOnlyMap.Remove(streamId);
                _             = _stateOnlyRemovalQueue.TryRemove(state);
                state._stream = stream;
            }

            Http2StreamState streamState = stream.State;

            if (Http2StreamState.ReservedRemote == streamState || Http2StreamState.ReservedLocal == streamState)
            {
                state.SetStreamReservedOrActivated();
                // wasStreamReservedOrActivated is part of the comparator for stateOnlyRemovalQueue there is no
                // need to reprioritize here because it will not be in stateOnlyRemovalQueue.
            }

            _ = stream.SetProperty(_stateKey, state);
        }
Exemple #4
0
 public override void OnStreamClosed(IHttp2Stream stream)
 {
     try
     {
         // When a stream is closed, consume any remaining bytes so that they
         // are restored to the connection window.
         IFlowState state           = GetState(stream);
         int        unconsumedBytes = state.UnconsumedBytes;
         if (_ctx is object && unconsumedBytes > 0)
         {
             if (ConsumeAllBytes(state, unconsumedBytes))
             {
                 // As the user has no real control on when this callback is used we should better
                 // call flush() if we produced any window update to ensure we not stale.
                 _ = _ctx.Flush();
             }
         }
     }
     catch (Http2Exception)
     {
         throw;
     }
     finally
     {
         // Unconditionally reduce the amount of memory required for flow control because there is no
         // object allocation costs associated with doing so and the stream will not have any more
         // local flow control state to keep track of anymore.
         _ = stream.SetProperty(_stateKey, REDUCED_FLOW_STATE);
     }
 }
        /// <summary>
        /// Make <paramref name="message"/> be the state associated with <paramref name="stream"/>.
        /// </summary>
        /// <param name="stream">The stream which <paramref name="message"/> is associated with.</param>
        /// <param name="message">The message which contains the HTTP semantics.</param>
        protected void PutMessage(IHttp2Stream stream, IFullHttpMessage message)
        {
            IFullHttpMessage previous = stream.SetProperty <IFullHttpMessage>(_messageKey, message);

            if (previous != message && previous is object)
            {
                _ = previous.Release();
            }
        }
Exemple #6
0
 public override void OnStreamAdded(IHttp2Stream stream)
 {
     _ = stream.SetProperty(_stateKey, new State(this, stream));
 }
Exemple #7
0
 public override void OnStreamAdded(IHttp2Stream stream)
 {
     // If the stream state is not open then the stream is not yet eligible for flow controlled frames and
     // only requires the ReducedFlowState. Otherwise the full amount of memory is required.
     _ = stream.SetProperty(_stateKey, new FlowState(this, stream));
 }
Exemple #8
0
 public override void OnStreamActive(IHttp2Stream stream)
 {
     // Need to be sure the stream's initial window is adjusted for SETTINGS
     // frames which may have been exchanged while it was in IDLE
     _ = stream.SetProperty(_stateKey, new DefaultState(this, stream, _initialWindowSize));
 }
Exemple #9
0
 public override void OnStreamAdded(IHttp2Stream stream)
 {
     // Unconditionally used the reduced flow control state because it requires no object allocation
     // and the DefaultFlowState will be allocated in onStreamActive.
     _ = stream.SetProperty(_stateKey, REDUCED_FLOW_STATE);
 }