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 1412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1423 NetLog::TYPE_SPDY_SESSION_RECV_DATA, | 1423 NetLog::TYPE_SPDY_SESSION_RECV_DATA, |
1424 base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin)); | 1424 base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin)); |
1425 } | 1425 } |
1426 | 1426 |
1427 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); | 1427 ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); |
1428 | 1428 |
1429 // By the time data comes in, the stream may already be inactive. | 1429 // By the time data comes in, the stream may already be inactive. |
1430 if (it == active_streams_.end()) | 1430 if (it == active_streams_.end()) |
1431 return; | 1431 return; |
1432 | 1432 |
1433 // Only decrease the window size for data for active streams. | |
1434 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION && len > 0) | |
1435 DecreaseRecvWindowSize(static_cast<int32>(len)); | |
1436 | |
1437 scoped_ptr<SpdyBuffer> buffer; | 1433 scoped_ptr<SpdyBuffer> buffer; |
1438 if (data) { | 1434 if (data) { |
1439 DCHECK_GT(len, 0u); | 1435 DCHECK_GT(len, 0u); |
1440 buffer.reset(new SpdyBuffer(data, len)); | 1436 buffer.reset(new SpdyBuffer(data, len)); |
| 1437 |
| 1438 if (flow_control_state_ == FLOW_CONTROL_STREAM_AND_SESSION) { |
| 1439 DecreaseRecvWindowSize(static_cast<int32>(len)); |
| 1440 buffer->AddConsumeCallback( |
| 1441 base::Bind(&SpdySession::IncreaseRecvWindowSize, |
| 1442 weak_factory_.GetWeakPtr())); |
| 1443 } |
1441 } else { | 1444 } else { |
1442 DCHECK_EQ(len, 0u); | 1445 DCHECK_EQ(len, 0u); |
1443 } | 1446 } |
1444 it->second->OnDataReceived(buffer.Pass()); | 1447 it->second->OnDataReceived(buffer.Pass()); |
1445 } | 1448 } |
1446 | 1449 |
1447 void SpdySession::OnSetting(SpdySettingsIds id, | 1450 void SpdySession::OnSetting(SpdySettingsIds id, |
1448 uint8 flags, | 1451 uint8 flags, |
1449 uint32 value) { | 1452 uint32 value) { |
1450 HandleSetting(id, value); | 1453 HandleSetting(id, value); |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1826 | 1829 |
1827 void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id, | 1830 void SpdySession::SendStreamWindowUpdate(SpdyStreamId stream_id, |
1828 uint32 delta_window_size) { | 1831 uint32 delta_window_size) { |
1829 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); | 1832 CHECK_GE(flow_control_state_, FLOW_CONTROL_STREAM); |
1830 CHECK(IsStreamActive(stream_id)); | 1833 CHECK(IsStreamActive(stream_id)); |
1831 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; | 1834 scoped_refptr<SpdyStream> stream = active_streams_[stream_id]; |
1832 CHECK_EQ(stream->stream_id(), stream_id); | 1835 CHECK_EQ(stream->stream_id(), stream_id); |
1833 SendWindowUpdateFrame(stream_id, delta_window_size, stream->priority()); | 1836 SendWindowUpdateFrame(stream_id, delta_window_size, stream->priority()); |
1834 } | 1837 } |
1835 | 1838 |
1836 void SpdySession::IncreaseRecvWindowSize(int32 delta_window_size) { | |
1837 if (flow_control_state_ < FLOW_CONTROL_STREAM_AND_SESSION) | |
1838 return; | |
1839 | |
1840 DCHECK_GE(session_unacked_recv_window_bytes_, 0); | |
1841 DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_); | |
1842 DCHECK_GE(delta_window_size, 1); | |
1843 // Check for overflow. | |
1844 DCHECK_LE(delta_window_size, kint32max - session_recv_window_size_); | |
1845 | |
1846 session_recv_window_size_ += delta_window_size; | |
1847 net_log_.AddEvent( | |
1848 NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, | |
1849 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | |
1850 delta_window_size, session_recv_window_size_)); | |
1851 | |
1852 session_unacked_recv_window_bytes_ += delta_window_size; | |
1853 if (session_unacked_recv_window_bytes_ > kSpdySessionInitialWindowSize / 2) { | |
1854 SendWindowUpdateFrame(kSessionFlowControlStreamId, | |
1855 session_unacked_recv_window_bytes_, | |
1856 HIGHEST); | |
1857 session_unacked_recv_window_bytes_ = 0; | |
1858 } | |
1859 } | |
1860 | |
1861 // Given a cwnd that we would have sent to the server, modify it based on the | 1839 // Given a cwnd that we would have sent to the server, modify it based on the |
1862 // field trial policy. | 1840 // field trial policy. |
1863 uint32 ApplyCwndFieldTrialPolicy(int cwnd) { | 1841 uint32 ApplyCwndFieldTrialPolicy(int cwnd) { |
1864 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd"); | 1842 base::FieldTrial* trial = base::FieldTrialList::Find("SpdyCwnd"); |
1865 if (!trial) { | 1843 if (!trial) { |
1866 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList"; | 1844 LOG(WARNING) << "Could not find \"SpdyCwnd\" in FieldTrialList"; |
1867 return cwnd; | 1845 return cwnd; |
1868 } | 1846 } |
1869 if (trial->group_name() == "cwnd10") | 1847 if (trial->group_name() == "cwnd10") |
1870 return 10; | 1848 return 10; |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2301 DCHECK_GE(session_send_window_size_, delta_window_size); | 2279 DCHECK_GE(session_send_window_size_, delta_window_size); |
2302 | 2280 |
2303 session_send_window_size_ -= delta_window_size; | 2281 session_send_window_size_ -= delta_window_size; |
2304 | 2282 |
2305 net_log_.AddEvent( | 2283 net_log_.AddEvent( |
2306 NetLog::TYPE_SPDY_SESSION_UPDATE_SEND_WINDOW, | 2284 NetLog::TYPE_SPDY_SESSION_UPDATE_SEND_WINDOW, |
2307 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 2285 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
2308 -delta_window_size, session_send_window_size_)); | 2286 -delta_window_size, session_send_window_size_)); |
2309 } | 2287 } |
2310 | 2288 |
| 2289 void SpdySession::IncreaseRecvWindowSize(size_t delta_window_size) { |
| 2290 if (flow_control_state_ < FLOW_CONTROL_STREAM_AND_SESSION) |
| 2291 return; |
| 2292 |
| 2293 DCHECK_GE(session_unacked_recv_window_bytes_, 0); |
| 2294 DCHECK_GE(session_recv_window_size_, session_unacked_recv_window_bytes_); |
| 2295 DCHECK_GE(delta_window_size, 1u); |
| 2296 // Check for overflow. |
| 2297 DCHECK_LE(delta_window_size, |
| 2298 static_cast<size_t>(kint32max - session_recv_window_size_)); |
| 2299 |
| 2300 session_recv_window_size_ += delta_window_size; |
| 2301 net_log_.AddEvent( |
| 2302 NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, |
| 2303 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
| 2304 delta_window_size, session_recv_window_size_)); |
| 2305 |
| 2306 session_unacked_recv_window_bytes_ += delta_window_size; |
| 2307 if (session_unacked_recv_window_bytes_ > kSpdySessionInitialWindowSize / 2) { |
| 2308 SendWindowUpdateFrame(kSessionFlowControlStreamId, |
| 2309 session_unacked_recv_window_bytes_, |
| 2310 HIGHEST); |
| 2311 session_unacked_recv_window_bytes_ = 0; |
| 2312 } |
| 2313 } |
| 2314 |
2311 void SpdySession::DecreaseRecvWindowSize(int32 delta_window_size) { | 2315 void SpdySession::DecreaseRecvWindowSize(int32 delta_window_size) { |
2312 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); | 2316 DCHECK_EQ(flow_control_state_, FLOW_CONTROL_STREAM_AND_SESSION); |
2313 DCHECK_GE(delta_window_size, 1); | 2317 DCHECK_GE(delta_window_size, 1); |
2314 | 2318 |
2315 // |delta_window_size| should never cause | 2319 // |delta_window_size| should never cause |
2316 // |session_recv_window_size_| to go negative. If we do, it's a | 2320 // |session_recv_window_size_| to go negative. If we do, it's a |
2317 // client-side bug. | 2321 // client-side bug. |
2318 if (delta_window_size > session_recv_window_size_) { | 2322 if (delta_window_size > session_recv_window_size_) { |
2319 NOTREACHED() << "Received session WINDOW_UPDATE with an " | 2323 NOTREACHED() << "Received session WINDOW_UPDATE with an " |
2320 << "invalid delta_window_size " << delta_window_size; | 2324 << "invalid delta_window_size " << delta_window_size; |
2321 // TODO(akalin): Figure out whether we should instead send a | 2325 // TODO(akalin): Figure out whether we should instead send a |
2322 // GOAWAY and close the connection here. | 2326 // GOAWAY and close the connection here. |
2323 return; | 2327 return; |
2324 } | 2328 } |
2325 | 2329 |
2326 session_recv_window_size_ -= delta_window_size; | 2330 session_recv_window_size_ -= delta_window_size; |
2327 net_log_.AddEvent( | 2331 net_log_.AddEvent( |
2328 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, | 2332 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, |
2329 base::Bind(&NetLogSpdySessionWindowUpdateCallback, | 2333 base::Bind(&NetLogSpdySessionWindowUpdateCallback, |
2330 -delta_window_size, session_recv_window_size_)); | 2334 -delta_window_size, session_recv_window_size_)); |
2331 } | 2335 } |
2332 | 2336 |
2333 } // namespace net | 2337 } // namespace net |
OLD | NEW |