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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « net/spdy/chromium/spdy_session.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/spdy/chromium/spdy_session.h" 5 #include "net/spdy/chromium/spdy_session.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <map> 9 #include <map>
10 #include <utility> 10 #include <utility>
(...skipping 2105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2116 in_flight_write_stream_.reset(); 2116 in_flight_write_stream_.reset();
2117 } 2117 }
2118 } 2118 }
2119 2119
2120 write_state_ = WRITE_STATE_DO_WRITE; 2120 write_state_ = WRITE_STATE_DO_WRITE;
2121 return OK; 2121 return OK;
2122 } 2122 }
2123 2123
2124 void SpdySession::SendInitialData() { 2124 void SpdySession::SendInitialData() {
2125 DCHECK(enable_sending_initial_data_); 2125 DCHECK(enable_sending_initial_data_);
2126 DCHECK(buffered_spdy_framer_.get());
2126 2127
2127 auto connection_header_prefix_frame = base::MakeUnique<SpdySerializedFrame>( 2128 // Prepare initial SETTINGS frame. Only send settings that have a value
2128 const_cast<char*>(kHttp2ConnectionHeaderPrefix), 2129 // different from the protocol default value.
2129 kHttp2ConnectionHeaderPrefixSize, false /* take_ownership */);
2130 // Count the prefix as part of the subsequent SETTINGS frame.
2131 EnqueueSessionWrite(HIGHEST, SpdyFrameType::SETTINGS,
2132 std::move(connection_header_prefix_frame));
2133
2134 // First, notify the server about the settings they should use when
2135 // communicating with us. Only send settings that have a value different from
2136 // the protocol default value.
2137 SettingsMap settings_map; 2130 SettingsMap settings_map;
2138 for (auto setting : initial_settings_) { 2131 for (auto setting : initial_settings_) {
2139 if (!IsSpdySettingAtDefaultInitialValue(setting.first, setting.second)) { 2132 if (!IsSpdySettingAtDefaultInitialValue(setting.first, setting.second)) {
2140 settings_map.insert(setting); 2133 settings_map.insert(setting);
2141 } 2134 }
2142 } 2135 }
2143 SendSettings(settings_map); 2136 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_SETTINGS,
2137 base::Bind(&NetLogSpdySendSettingsCallback, &settings_map));
2138 std::unique_ptr<SpdySerializedFrame> settings_frame(
2139 buffered_spdy_framer_->CreateSettings(settings_map));
2144 2140
2145 // Next, notify the server about our initial recv window size. 2141 // Prepare initial WINDOW_UPDATE frame.
2146 // Bump up the receive window size to the real initial value. This 2142 // Make sure |session_max_recv_window_size_ - session_recv_window_size_|
2147 // has to go here since the WINDOW_UPDATE frame sent by 2143 // does not underflow.
2148 // IncreaseRecvWindowSize() call uses |buffered_spdy_framer_|.
2149 // This condition implies that |session_max_recv_window_size_| -
2150 // |session_recv_window_size_| doesn't overflow.
2151 DCHECK_GE(session_max_recv_window_size_, session_recv_window_size_); 2144 DCHECK_GE(session_max_recv_window_size_, session_recv_window_size_);
2152 DCHECK_GE(session_recv_window_size_, 0); 2145 DCHECK_GE(session_recv_window_size_, 0);
2153 if (session_max_recv_window_size_ > session_recv_window_size_) { 2146 std::unique_ptr<SpdySerializedFrame> window_update_frame;
2154 IncreaseRecvWindowSize(session_max_recv_window_size_ - 2147 bool send_window_update =
2155 session_recv_window_size_); 2148 session_max_recv_window_size_ > session_recv_window_size_;
2149 if (send_window_update) {
2150 DCHECK_GE(session_unacked_recv_window_bytes_, 0);
2151 DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_);
2152
2153 const int32_t delta_window_size =
2154 session_max_recv_window_size_ - session_recv_window_size_;
2155 session_recv_window_size_ += delta_window_size;
2156 net_log_.AddEvent(NetLogEventType::HTTP2_STREAM_UPDATE_RECV_WINDOW,
2157 base::Bind(&NetLogSpdySessionWindowUpdateCallback,
2158 delta_window_size, session_recv_window_size_));
2159
2160 session_unacked_recv_window_bytes_ += delta_window_size;
2161 if (session_unacked_recv_window_bytes_ <= session_max_recv_window_size_ / 2)
2162 send_window_update = false;
2156 } 2163 }
2157 }
2158 2164
2159 void SpdySession::SendSettings(const SettingsMap& settings) { 2165 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
2160 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_SETTINGS, 2166 net_log_.AddEvent(NetLogEventType::HTTP2_SESSION_SEND_WINDOW_UPDATE,
2161 base::Bind(&NetLogSpdySendSettingsCallback, &settings)); 2167 base::Bind(&NetLogSpdyWindowUpdateFrameCallback,
2162 // Create the SETTINGS frame and send it. 2168 kSessionFlowControlStreamId,
2163 DCHECK(buffered_spdy_framer_.get()); 2169 session_unacked_recv_window_bytes_));
2164 std::unique_ptr<SpdySerializedFrame> settings_frame( 2170 window_update_frame = buffered_spdy_framer_->CreateWindowUpdate(
2165 buffered_spdy_framer_->CreateSettings(settings)); 2171 kSessionFlowControlStreamId, session_unacked_recv_window_bytes_);
2172 session_unacked_recv_window_bytes_ = 0;
2173 }
2174
2175 // Create a single frame to hold connection prefix, initial SETTINGS frame,
2176 // and optional initial WINDOW_UPDATE frame, so that they are sent on the wire
2177 // in a single packet.
2178 size_t initial_frame_size =
2179 kHttp2ConnectionHeaderPrefixSize + settings_frame->size();
2180 if (send_window_update)
2181 initial_frame_size += window_update_frame->size();
2182 auto initial_frame_data = base::MakeUnique<char[]>(initial_frame_size);
2183 size_t offset = 0;
2184
2185 memcpy(initial_frame_data.get() + offset, kHttp2ConnectionHeaderPrefix,
2186 kHttp2ConnectionHeaderPrefixSize);
2187 offset += kHttp2ConnectionHeaderPrefixSize;
2188
2189 memcpy(initial_frame_data.get() + offset, settings_frame->data(),
2190 settings_frame->size());
2191 offset += settings_frame->size();
2192
2193 if (send_window_update) {
2194 memcpy(initial_frame_data.get() + offset, window_update_frame->data(),
2195 window_update_frame->size());
2196 }
2197
2198 auto initial_frame = base::MakeUnique<SpdySerializedFrame>(
2199 initial_frame_data.release(), initial_frame_size,
2200 /* owns_buffer = */ true);
2166 EnqueueSessionWrite(HIGHEST, SpdyFrameType::SETTINGS, 2201 EnqueueSessionWrite(HIGHEST, SpdyFrameType::SETTINGS,
2167 std::move(settings_frame)); 2202 std::move(initial_frame));
2168 } 2203 }
2169 2204
2170 void SpdySession::HandleSetting(uint32_t id, uint32_t value) { 2205 void SpdySession::HandleSetting(uint32_t id, uint32_t value) {
2171 switch (id) { 2206 switch (id) {
2172 case SETTINGS_MAX_CONCURRENT_STREAMS: 2207 case SETTINGS_MAX_CONCURRENT_STREAMS:
2173 max_concurrent_streams_ = 2208 max_concurrent_streams_ =
2174 std::min(static_cast<size_t>(value), kMaxConcurrentStreamLimit); 2209 std::min(static_cast<size_t>(value), kMaxConcurrentStreamLimit);
2175 ProcessPendingStreamRequests(); 2210 ProcessPendingStreamRequests();
2176 break; 2211 break;
2177 case SETTINGS_INITIAL_WINDOW_SIZE: { 2212 case SETTINGS_INITIAL_WINDOW_SIZE: {
(...skipping 1011 matching lines...) Expand 10 before | Expand all | Expand 10 after
3189 if (!queue->empty()) { 3224 if (!queue->empty()) {
3190 SpdyStreamId stream_id = queue->front(); 3225 SpdyStreamId stream_id = queue->front();
3191 queue->pop_front(); 3226 queue->pop_front();
3192 return stream_id; 3227 return stream_id;
3193 } 3228 }
3194 } 3229 }
3195 return 0; 3230 return 0;
3196 } 3231 }
3197 3232
3198 } // namespace net 3233 } // namespace net
OLDNEW
« 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