Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(436)

Unified Diff: net/spdy/chromium/spdy_session.cc

Issue 2909653002: SpdySession: Combine three frames into a single packet. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/chromium/spdy_session.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/chromium/spdy_session.cc
diff --git a/net/spdy/chromium/spdy_session.cc b/net/spdy/chromium/spdy_session.cc
index 7158a1fa84eaf68e418da894fa7fab301e07fe1d..6e0fa6dff87d9d8d60d193bc297886bb2edc6dc0 100644
--- a/net/spdy/chromium/spdy_session.cc
+++ b/net/spdy/chromium/spdy_session.cc
@@ -2123,48 +2123,83 @@ int SpdySession::DoWriteComplete(int result) {
void SpdySession::SendInitialData() {
DCHECK(enable_sending_initial_data_);
+ DCHECK(buffered_spdy_framer_.get());
- auto connection_header_prefix_frame = base::MakeUnique<SpdySerializedFrame>(
- const_cast<char*>(kHttp2ConnectionHeaderPrefix),
- kHttp2ConnectionHeaderPrefixSize, false /* take_ownership */);
- // Count the prefix as part of the subsequent SETTINGS frame.
- EnqueueSessionWrite(HIGHEST, SpdyFrameType::SETTINGS,
- std::move(connection_header_prefix_frame));
-
- // First, notify the server about the settings they should use when
- // communicating with us. Only send settings that have a value different from
- // the protocol default value.
+ // Prepare initial SETTINGS frame. Only send settings that have a value
+ // different from the protocol default value.
SettingsMap settings_map;
for (auto setting : initial_settings_) {
if (!IsSpdySettingAtDefaultInitialValue(setting.first, setting.second)) {
settings_map.insert(setting);
}
}
- SendSettings(settings_map);
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_SETTINGS,
+ base::Bind(&NetLogSpdySendSettingsCallback, &settings_map));
+ std::unique_ptr<SpdySerializedFrame> settings_frame(
+ buffered_spdy_framer_->CreateSettings(settings_map));
- // Next, notify the server about our initial recv window size.
- // Bump up the receive window size to the real initial value. This
- // has to go here since the WINDOW_UPDATE frame sent by
- // IncreaseRecvWindowSize() call uses |buffered_spdy_framer_|.
- // This condition implies that |session_max_recv_window_size_| -
- // |session_recv_window_size_| doesn't overflow.
+ // Prepare initial WINDOW_UPDATE frame.
+ // Make sure |session_max_recv_window_size_ - session_recv_window_size_|
+ // does not underflow.
DCHECK_GE(session_max_recv_window_size_, session_recv_window_size_);
DCHECK_GE(session_recv_window_size_, 0);
- if (session_max_recv_window_size_ > session_recv_window_size_) {
- IncreaseRecvWindowSize(session_max_recv_window_size_ -
- session_recv_window_size_);
+ std::unique_ptr<SpdySerializedFrame> window_update_frame;
+ bool send_window_update =
+ session_max_recv_window_size_ > session_recv_window_size_;
+ if (send_window_update) {
+ DCHECK_GE(session_unacked_recv_window_bytes_, 0);
+ DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_);
+
+ const int32_t delta_window_size =
+ session_max_recv_window_size_ - session_recv_window_size_;
+ session_recv_window_size_ += delta_window_size;
+ net_log_.AddEvent(NetLogEventType::HTTP2_STREAM_UPDATE_RECV_WINDOW,
+ base::Bind(&NetLogSpdySessionWindowUpdateCallback,
+ delta_window_size, session_recv_window_size_));
+
+ session_unacked_recv_window_bytes_ += delta_window_size;
+ if (session_unacked_recv_window_bytes_ <= session_max_recv_window_size_ / 2)
+ send_window_update = false;
+ }
+
+ if (send_window_update) {
Zhongyi Shi 2017/05/30 23:10:49 nit: If I understand the code correctly, the previ
Bence 2017/06/05 17:19:02 I agree with you that this logic flow is unnecessa
+ net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_WINDOW_UPDATE,
+ base::Bind(&NetLogSpdyWindowUpdateFrameCallback,
+ kSessionFlowControlStreamId,
+ session_unacked_recv_window_bytes_));
+ window_update_frame = buffered_spdy_framer_->CreateWindowUpdate(
+ kSessionFlowControlStreamId, session_unacked_recv_window_bytes_);
+ session_unacked_recv_window_bytes_ = 0;
}
-}
-void SpdySession::SendSettings(const SettingsMap& settings) {
- net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_SETTINGS,
- base::Bind(&NetLogSpdySendSettingsCallback, &settings));
- // Create the SETTINGS frame and send it.
- DCHECK(buffered_spdy_framer_.get());
- std::unique_ptr<SpdySerializedFrame> settings_frame(
- buffered_spdy_framer_->CreateSettings(settings));
+ // Create a single frame to hold connection prefix, initial SETTINGS frame,
+ // and optional initial WINDOW_UPDATE frame, so that they are sent on the wire
+ // in a single packet.
+ size_t initial_frame_size =
+ kHttp2ConnectionHeaderPrefixSize + settings_frame->size();
+ if (send_window_update)
+ initial_frame_size += window_update_frame->size();
+ auto initial_frame_data = base::MakeUnique<char[]>(initial_frame_size);
+ size_t offset = 0;
+
+ memcpy(initial_frame_data.get() + offset, kHttp2ConnectionHeaderPrefix,
+ kHttp2ConnectionHeaderPrefixSize);
+ offset += kHttp2ConnectionHeaderPrefixSize;
+
+ memcpy(initial_frame_data.get() + offset, settings_frame->data(),
+ settings_frame->size());
+ offset += settings_frame->size();
+
+ if (send_window_update) {
+ memcpy(initial_frame_data.get() + offset, window_update_frame->data(),
+ window_update_frame->size());
+ }
+
+ auto initial_frame = base::MakeUnique<SpdySerializedFrame>(
+ initial_frame_data.release(), initial_frame_size,
+ /* owns_buffer = */ true);
EnqueueSessionWrite(HIGHEST, SpdyFrameType::SETTINGS,
- std::move(settings_frame));
+ std::move(initial_frame));
}
void SpdySession::HandleSetting(uint32_t id, uint32_t value) {
« no previous file with comments | « net/spdy/chromium/spdy_session.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698