OLD | NEW |
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/spdy_session.h" | 5 #include "net/spdy/spdy_session.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1395 NetLog::TYPE_SPDY_SESSION_RECV_DATA, | 1395 NetLog::TYPE_SPDY_SESSION_RECV_DATA, |
1396 base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin)); | 1396 base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin)); |
1397 } | 1397 } |
1398 | 1398 |
1399 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 1399 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
1400 | 1400 |
1401 // By the time data comes in, the stream may already be inactive. | 1401 // By the time data comes in, the stream may already be inactive. |
1402 if (it == active_streams_.end()) | 1402 if (it == active_streams_.end()) |
1403 return; | 1403 return; |
1404 | 1404 |
1405 // Only decrease the window size for data for active streams. | |
1406 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION && len > 0) | |
1407 DecreaseRecvWindowSize(static_cast<int32>(len)); | |
1408 | |
1409 scoped_ptr<SpdyBuffer> buffer; | 1405 scoped_ptr<SpdyBuffer> buffer; |
1410 if (data) { | 1406 if (data) { |
1411 DCHECK_GT(len, 0u); | 1407 DCHECK_GT(len, 0u); |
1412 buffer.reset(new SpdyBuffer(data, len)); | 1408 buffer.reset(new SpdyBuffer(data, len)); |
| 1409 |
| 1410 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { |
| 1411 DecreaseRecvWindowSize(static_cast<int32>(len)); |
| 1412 buffer->AddConsumeCallback( |
| 1413 base::Bind(&SpdySession::IncreaseRecvWindowSize, |
| 1414 weak_factory_.GetWeakPtr())); |
| 1415 } |
1413 } else { | 1416 } else { |
1414 DCHECK_EQ(len, 0u); | 1417 DCHECK_EQ(len, 0u); |
1415 } | 1418 } |
1416 it->second->OnDataReceived(buffer.Pass()); | 1419 it->second->OnDataReceived(buffer.Pass()); |
1417 } | 1420 } |
1418 | 1421 |
1419 void SpdySession::OnSetting(SpdySettingsIds id, | 1422 void SpdySession::OnSetting(SpdySettingsIds id, |
1420 uint8 flags, | 1423 uint8 flags, |
1421 uint32 value) { | 1424 uint32 value) { |
1422 HandleSetting(id, value); | 1425 HandleSetting(id, value); |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1798 | 1801 |
1799 void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id, | 1802 void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id, |
1800 uint32 delta_window_size) { | 1803 uint32 delta_window_size) { |
1801 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); | 1804 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); |
1802 CHECK(IsStreamActive(stream_id)); | 1805 CHECK(IsStreamActive(stream_id)); |
1803 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 1806 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
1804 CHECK_EQ(stream->stream_id(), stream_id); | 1807 CHECK_EQ(stream->stream_id(), stream_id); |
1805 SendWindowUpdateFrame(stream_id, delta_window_size, stream->priority()); | 1808 SendWindowUpdateFrame(stream_id, delta_window_size, stream->priority()); |
1806 } | 1809 } |
1807 | 1810 |
1808 void SpdySession::IncreaseRecvWindowSize(int32 delta_window_size) { | |
1809 if (flow_control_state_ < FLOW_CONTROL_STREAM_AND_SESSION) | |
1810 return; | |
1811 | |
1812 DCHECK_GE(session_unacked_recv_window_bytes_, 0); | |
1813 DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_); | |
1814 DCHECK_GE(delta_window_size, 1); | |
1815 // Check for overflow. | |
1816 DCHECK_LE(delta_window_size, kint32max - session_recv_window_size_); | |
1817 | |
1818 session_recv_window_size_ += delta_window_size; | |
1819 net_log_.AddEvent( | |
1820 NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, | |
1821 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | |
1822 delta_window_size, session_recv_window_size_)); | |
1823 | |
1824 session_unacked_recv_window_bytes_ += delta_window_size; | |
1825 if (session_unacked_recv_window_bytes_ > kSpdySessionInitialWindowSize / 2) { | |
1826 SendWindowUpdateFrame(kSessionFlowControlStreamId, | |
1827 session_unacked_recv_window_bytes_, | |
1828 HIGHEST); | |
1829 session_unacked_recv_window_bytes_ = 0; | |
1830 } | |
1831 } | |
1832 | |
1833 // Given a cwnd that we would have sent to the server, modify it based on the | 1811 // Given a cwnd that we would have sent to the server, modify it based on the |
1834 // field trial policy. | 1812 // field trial policy. |
1835 uint32 ApplyCwndFieldTrialPolicy(int cwnd) { | 1813 uint32 ApplyCwndFieldTrialPolicy(int cwnd) { |
1836 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd"); | 1814 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd"); |
1837 if (!trial) { | 1815 if (!trial) { |
1838 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList"; | 1816 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList"; |
1839 return cwnd; | 1817 return cwnd; |
1840 } | 1818 } |
1841 if (trial->group_name() == "cwnd10") | 1819 if (trial->group_name() == "cwnd10") |
1842 return 10; | 1820 return 10; |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2273 DCHECK_GE(session_send_window_size_, delta_window_size); | 2251 DCHECK_GE(session_send_window_size_, delta_window_size); |
2274 | 2252 |
2275 session_send_window_size_ -= delta_window_size; | 2253 session_send_window_size_ -= delta_window_size; |
2276 | 2254 |
2277 net_log_.AddEvent( | 2255 net_log_.AddEvent( |
2278 NetLog::TYPE_SPDY_SESSION_UPDATE_SEND_WINDOW, | 2256 NetLog::TYPE_SPDY_SESSION_UPDATE_SEND_WINDOW, |
2279 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 2257 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
2280 -delta_window_size, session_send_window_size_)); | 2258 -delta_window_size, session_send_window_size_)); |
2281 } | 2259 } |
2282 | 2260 |
| 2261 void SpdySession::IncreaseRecvWindowSize(size_t delta_window_size) { |
| 2262 if (flow_control_state_ < FLOW_CONTROL_STREAM_AND_SESSION) |
| 2263 return; |
| 2264 |
| 2265 DCHECK_GE(session_unacked_recv_window_bytes_, 0); |
| 2266 DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_); |
| 2267 DCHECK_GE(delta_window_size, 1u); |
| 2268 // Check for overflow. |
| 2269 DCHECK_LE(delta_window_size, |
| 2270 static_cast<size_t>(kint32max - session_recv_window_size_)); |
| 2271 |
| 2272 session_recv_window_size_ += delta_window_size; |
| 2273 net_log_.AddEvent( |
| 2274 NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, |
| 2275 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
| 2276 delta_window_size, session_recv_window_size_)); |
| 2277 |
| 2278 session_unacked_recv_window_bytes_ += delta_window_size; |
| 2279 if (session_unacked_recv_window_bytes_ > kSpdySessionInitialWindowSize / 2) { |
| 2280 SendWindowUpdateFrame(kSessionFlowControlStreamId, |
| 2281 session_unacked_recv_window_bytes_, |
| 2282 HIGHEST); |
| 2283 session_unacked_recv_window_bytes_ = 0; |
| 2284 } |
| 2285 } |
| 2286 |
2283 void SpdySession::DecreaseRecvWindowSize(int32 delta_window_size) { | 2287 void SpdySession::DecreaseRecvWindowSize(int32 delta_window_size) { |
2284 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); | 2288 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); |
2285 DCHECK_GE(delta_window_size, 1); | 2289 DCHECK_GE(delta_window_size, 1); |
2286 | 2290 |
2287 // |delta_window_size| should never cause | 2291 // |delta_window_size| should never cause |
2288 // |session_recv_window_size_| to go negative. If we do, it's a | 2292 // |session_recv_window_size_| to go negative. If we do, it's a |
2289 // client-side bug. | 2293 // client-side bug. |
2290 if (delta_window_size > session_recv_window_size_) { | 2294 if (delta_window_size > session_recv_window_size_) { |
2291 NOTREACHED() << "Received session WINDOW_UPDATE with an " | 2295 NOTREACHED() << "Received session WINDOW_UPDATE with an " |
2292 << "invalid delta_window_size " << delta_window_size; | 2296 << "invalid delta_window_size " << delta_window_size; |
2293 // TODO(akalin): Figure out whether we should instead send a | 2297 // TODO(akalin): Figure out whether we should instead send a |
2294 // GOAWAY and close the connection here. | 2298 // GOAWAY and close the connection here. |
2295 return; | 2299 return; |
2296 } | 2300 } |
2297 | 2301 |
2298 session_recv_window_size_ -= delta_window_size; | 2302 session_recv_window_size_ -= delta_window_size; |
2299 net_log_.AddEvent( | 2303 net_log_.AddEvent( |
2300 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, | 2304 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, |
2301 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 2305 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
2302 -delta_window_size, session_recv_window_size_)); | 2306 -delta_window_size, session_recv_window_size_)); |
2303 } | 2307 } |
2304 | 2308 |
2305 } // namespace net | 2309 } // namespace net |
OLD | NEW |