Uses `quiche::QuicheCircularDeque` as the type backing the pending frame queue, rather than `std::list`. `QuicheCircularDeque` is much more memory- and CPU-efficient. Protected by does not affect the GFE2 binary; not protected. PiperOrigin-RevId: 852538036
diff --git a/quiche/http2/adapter/oghttp2_session.cc b/quiche/http2/adapter/oghttp2_session.cc index 88eab8e..f345ec7 100644 --- a/quiche/http2/adapter/oghttp2_session.cc +++ b/quiche/http2/adapter/oghttp2_session.cc
@@ -696,6 +696,10 @@ // Serialize and send frames in the queue. while (!frames_.empty()) { const auto& frame_ptr = frames_.front(); + if (frame_ptr == nullptr) { + frames_.pop_front(); + continue; + } FrameAttributeCollector c; frame_ptr->Visit(&c); @@ -1960,11 +1964,10 @@ for (auto it = frames_.begin(); frames_remaining > 0 && it != frames_.end();) { if (static_cast<Http2StreamId>((*it)->stream_id()) == stream_id) { - it = frames_.erase(it); + *it = nullptr; --frames_remaining; - } else { - ++it; } + ++it; } } if (write_scheduler_.StreamRegistered(stream_id)) { @@ -2051,9 +2054,11 @@ // TODO(diannahu): Consider informing the visitor of dropped frames. This may // mean keeping the frames and invoking a frame-not-sent callback, similar to // nghttp2. Could add a closure to each frame in the frames queue. - frames_.remove_if([](const auto& frame) { - return frame->frame_type() != spdy::SpdyFrameType::RST_STREAM; - }); + for (std::unique_ptr<spdy::SpdyFrameIR>& frame : frames_) { + if (frame->frame_type() != spdy::SpdyFrameType::RST_STREAM) { + frame = nullptr; + } + }; if (initial_settings != nullptr) { frames_.push_front(std::move(initial_settings));
diff --git a/quiche/http2/adapter/oghttp2_session.h b/quiche/http2/adapter/oghttp2_session.h index 19d3545..b788cb0 100644 --- a/quiche/http2/adapter/oghttp2_session.h +++ b/quiche/http2/adapter/oghttp2_session.h
@@ -508,8 +508,9 @@ quiche::QuicheLinkedHashMap<Http2StreamId, PendingStreamState> pending_streams_; - // The queue of outbound frames. - std::list<std::unique_ptr<spdy::SpdyFrameIR>> frames_; + // The queue of outbound frames. May contain nullptr entries for frames that + // have been removed from the queue. + quiche::QuicheCircularDeque<std::unique_ptr<spdy::SpdyFrameIR>> frames_; // Buffered data (connection preface, serialized frames) that has not yet been // sent. ChunkedBuffer buffered_data_;