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 |