| 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_stream.h" | 5 #include "net/spdy/spdy_stream.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 DCHECK_GE(send_window_size_, delta_window_size); | 304 DCHECK_GE(send_window_size_, delta_window_size); |
| 305 | 305 |
| 306 send_window_size_ -= delta_window_size; | 306 send_window_size_ -= delta_window_size; |
| 307 | 307 |
| 308 net_log_.AddEvent( | 308 net_log_.AddEvent( |
| 309 NetLog::TYPE_SPDY_STREAM_UPDATE_SEND_WINDOW, | 309 NetLog::TYPE_SPDY_STREAM_UPDATE_SEND_WINDOW, |
| 310 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, | 310 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, |
| 311 stream_id_, -delta_window_size, send_window_size_)); | 311 stream_id_, -delta_window_size, send_window_size_)); |
| 312 } | 312 } |
| 313 | 313 |
| 314 void SpdyStream::IncreaseRecvWindowSize(int32 delta_window_size) { | |
| 315 if (session_->flow_control_state() < SpdySession::FLOW_CONTROL_STREAM) | |
| 316 return; | |
| 317 | |
| 318 // Call back into the session, since this is the only | |
| 319 // window-size-related function that is called by the delegate | |
| 320 // instead of by the session. | |
| 321 session_->IncreaseRecvWindowSize(delta_window_size); | |
| 322 | |
| 323 // By the time a read is processed by the delegate, this stream may | |
| 324 // already be inactive. | |
| 325 if (!session_->IsStreamActive(stream_id_)) | |
| 326 return; | |
| 327 | |
| 328 DCHECK_GE(unacked_recv_window_bytes_, 0); | |
| 329 DCHECK_GE(recv_window_size_, unacked_recv_window_bytes_); | |
| 330 DCHECK_GE(delta_window_size, 1); | |
| 331 // Check for overflow. | |
| 332 DCHECK_LE(delta_window_size, kint32max - recv_window_size_); | |
| 333 | |
| 334 recv_window_size_ += delta_window_size; | |
| 335 net_log_.AddEvent( | |
| 336 NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, | |
| 337 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, | |
| 338 stream_id_, delta_window_size, recv_window_size_)); | |
| 339 | |
| 340 unacked_recv_window_bytes_ += delta_window_size; | |
| 341 if (unacked_recv_window_bytes_ > | |
| 342 session_->stream_initial_recv_window_size() / 2) { | |
| 343 session_->SendStreamWindowUpdate( | |
| 344 stream_id_, static_cast<uint32>(unacked_recv_window_bytes_)); | |
| 345 unacked_recv_window_bytes_ = 0; | |
| 346 } | |
| 347 } | |
| 348 | |
| 349 int SpdyStream::GetPeerAddress(IPEndPoint* address) const { | 314 int SpdyStream::GetPeerAddress(IPEndPoint* address) const { |
| 350 return session_->GetPeerAddress(address); | 315 return session_->GetPeerAddress(address); |
| 351 } | 316 } |
| 352 | 317 |
| 353 int SpdyStream::GetLocalAddress(IPEndPoint* address) const { | 318 int SpdyStream::GetLocalAddress(IPEndPoint* address) const { |
| 354 return session_->GetLocalAddress(address); | 319 return session_->GetLocalAddress(address); |
| 355 } | 320 } |
| 356 | 321 |
| 357 bool SpdyStream::WasEverUsed() const { | 322 bool SpdyStream::WasEverUsed() const { |
| 358 return session_->WasEverUsed(); | 323 return session_->WasEverUsed(); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 | 446 |
| 482 if (!buffer) { | 447 if (!buffer) { |
| 483 metrics_.StopStream(); | 448 metrics_.StopStream(); |
| 484 session_->CloseStream(stream_id_, net::OK); | 449 session_->CloseStream(stream_id_, net::OK); |
| 485 // Note: |this| may be deleted after calling CloseStream. | 450 // Note: |this| may be deleted after calling CloseStream. |
| 486 return; | 451 return; |
| 487 } | 452 } |
| 488 | 453 |
| 489 size_t length = buffer->GetRemainingSize(); | 454 size_t length = buffer->GetRemainingSize(); |
| 490 DCHECK_LE(length, session_->GetDataFrameMaximumPayload()); | 455 DCHECK_LE(length, session_->GetDataFrameMaximumPayload()); |
| 491 if (session_->flow_control_state() >= SpdySession::FLOW_CONTROL_STREAM) | 456 if (session_->flow_control_state() >= SpdySession::FLOW_CONTROL_STREAM) { |
| 492 DecreaseRecvWindowSize(static_cast<int32>(length)); | 457 DecreaseRecvWindowSize(static_cast<int32>(length)); |
| 458 buffer->AddConsumeCallback( |
| 459 base::Bind(&SpdyStream::IncreaseRecvWindowSize, |
| 460 weak_ptr_factory_.GetWeakPtr())); |
| 461 } |
| 493 | 462 |
| 494 // Track our bandwidth. | 463 // Track our bandwidth. |
| 495 metrics_.RecordBytes(length); | 464 metrics_.RecordBytes(length); |
| 496 recv_bytes_ += length; | 465 recv_bytes_ += length; |
| 497 recv_last_byte_time_ = base::TimeTicks::Now(); | 466 recv_last_byte_time_ = base::TimeTicks::Now(); |
| 498 | 467 |
| 499 if (delegate_->OnDataReceived(buffer.Pass()) != net::OK) { | 468 if (delegate_->OnDataReceived(buffer.Pass()) != net::OK) { |
| 500 // |delegate_| rejected the data. | 469 // |delegate_| rejected the data. |
| 501 LogStreamError(ERR_SPDY_PROTOCOL_ERROR, "Delegate rejected the data"); | 470 LogStreamError(ERR_SPDY_PROTOCOL_ERROR, "Delegate rejected the data"); |
| 502 session_->CloseStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR); | 471 session_->CloseStream(stream_id_, ERR_SPDY_PROTOCOL_ERROR); |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 913 recv_first_byte_time_ - send_time_); | 882 recv_first_byte_time_ - send_time_); |
| 914 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime", | 883 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime", |
| 915 recv_last_byte_time_ - recv_first_byte_time_); | 884 recv_last_byte_time_ - recv_first_byte_time_); |
| 916 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", | 885 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", |
| 917 recv_last_byte_time_ - send_time_); | 886 recv_last_byte_time_ - send_time_); |
| 918 | 887 |
| 919 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); | 888 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); |
| 920 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); | 889 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); |
| 921 } | 890 } |
| 922 | 891 |
| 892 void SpdyStream::IncreaseRecvWindowSize(size_t delta_window_size) { |
| 893 if (session_->flow_control_state() < SpdySession::FLOW_CONTROL_STREAM) |
| 894 return; |
| 895 |
| 896 // By the time a read is processed by the delegate, this stream may |
| 897 // already be inactive. |
| 898 if (!session_->IsStreamActive(stream_id_)) |
| 899 return; |
| 900 |
| 901 DCHECK_GE(unacked_recv_window_bytes_, 0); |
| 902 DCHECK_GE(recv_window_size_, unacked_recv_window_bytes_); |
| 903 DCHECK_GE(delta_window_size, 1u); |
| 904 // Check for overflow. |
| 905 DCHECK_LE(delta_window_size, |
| 906 static_cast<size_t>(kint32max - recv_window_size_)); |
| 907 |
| 908 recv_window_size_ += delta_window_size; |
| 909 net_log_.AddEvent( |
| 910 NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, |
| 911 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, |
| 912 stream_id_, delta_window_size, recv_window_size_)); |
| 913 |
| 914 unacked_recv_window_bytes_ += delta_window_size; |
| 915 if (unacked_recv_window_bytes_ > |
| 916 session_->stream_initial_recv_window_size() / 2) { |
| 917 session_->SendStreamWindowUpdate( |
| 918 stream_id_, static_cast<uint32>(unacked_recv_window_bytes_)); |
| 919 unacked_recv_window_bytes_ = 0; |
| 920 } |
| 921 } |
| 922 |
| 923 void SpdyStream::DecreaseRecvWindowSize(int32 delta_window_size) { | 923 void SpdyStream::DecreaseRecvWindowSize(int32 delta_window_size) { |
| 924 DCHECK(session_->IsStreamActive(stream_id_)); | 924 DCHECK(session_->IsStreamActive(stream_id_)); |
| 925 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); | 925 DCHECK_GE(session_->flow_control_state(), SpdySession::FLOW_CONTROL_STREAM); |
| 926 DCHECK_GE(delta_window_size, 1); | 926 DCHECK_GE(delta_window_size, 1); |
| 927 | 927 |
| 928 // Since we never decrease the initial window size, | 928 // Since we never decrease the initial window size, |
| 929 // |delta_window_size| should never cause |recv_window_size_| to go | 929 // |delta_window_size| should never cause |recv_window_size_| to go |
| 930 // negative. If we do, it's a client-side bug, so we use | 930 // negative. If we do, it's a client-side bug, so we use |
| 931 // PROTOCOL_ERROR for lack of a better error code. | 931 // PROTOCOL_ERROR for lack of a better error code. |
| 932 if (delta_window_size > recv_window_size_) { | 932 if (delta_window_size > recv_window_size_) { |
| 933 session_->ResetStream( | 933 session_->ResetStream( |
| 934 stream_id_, RST_STREAM_PROTOCOL_ERROR, | 934 stream_id_, RST_STREAM_PROTOCOL_ERROR, |
| 935 "Invalid delta_window_size for DecreaseRecvWindowSize"); | 935 "Invalid delta_window_size for DecreaseRecvWindowSize"); |
| 936 NOTREACHED(); | 936 NOTREACHED(); |
| 937 return; | 937 return; |
| 938 } | 938 } |
| 939 | 939 |
| 940 recv_window_size_ -= delta_window_size; | 940 recv_window_size_ -= delta_window_size; |
| 941 net_log_.AddEvent( | 941 net_log_.AddEvent( |
| 942 NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, | 942 NetLog::TYPE_SPDY_STREAM_UPDATE_RECV_WINDOW, |
| 943 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, | 943 base::Bind(&NetLogSpdyStreamWindowUpdateCallback, |
| 944 stream_id_, -delta_window_size, recv_window_size_)); | 944 stream_id_, -delta_window_size, recv_window_size_)); |
| 945 } | 945 } |
| 946 | 946 |
| 947 } // namespace net | 947 } // namespace net |
| OLD | NEW |