| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/singleton.h" | 9 #include "base/singleton.h" |
| 10 #include "net/spdy/spdy_session.h" | 10 #include "net/spdy/spdy_session.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 metrics_(Singleton<BandwidthMetrics>::get()), | 22 metrics_(Singleton<BandwidthMetrics>::get()), |
| 23 response_received_(false), | 23 response_received_(false), |
| 24 session_(session), | 24 session_(session), |
| 25 delegate_(NULL), | 25 delegate_(NULL), |
| 26 request_time_(base::Time::Now()), | 26 request_time_(base::Time::Now()), |
| 27 response_(new spdy::SpdyHeaderBlock), | 27 response_(new spdy::SpdyHeaderBlock), |
| 28 io_state_(STATE_NONE), | 28 io_state_(STATE_NONE), |
| 29 response_status_(OK), | 29 response_status_(OK), |
| 30 cancelled_(false), | 30 cancelled_(false), |
| 31 send_bytes_(0), | 31 send_bytes_(0), |
| 32 recv_bytes_(0), | 32 recv_bytes_(0) { |
| 33 histograms_recorded_(false) {} | 33 } |
| 34 | 34 |
| 35 SpdyStream::~SpdyStream() { | 35 SpdyStream::~SpdyStream() { |
| 36 DLOG(INFO) << "Deleting SpdyStream for stream " << stream_id_; | 36 DLOG(INFO) << "Deleting SpdyStream for stream " << stream_id_; |
| 37 UpdateHistograms(); |
| 37 } | 38 } |
| 38 | 39 |
| 39 void SpdyStream::SetDelegate(Delegate* delegate) { | 40 void SpdyStream::SetDelegate(Delegate* delegate) { |
| 40 CHECK(delegate); | 41 CHECK(delegate); |
| 41 delegate_ = delegate; | 42 delegate_ = delegate; |
| 42 | 43 |
| 43 if (pushed_) { | 44 if (pushed_) { |
| 44 CHECK(response_received()); | 45 CHECK(response_received()); |
| 45 MessageLoop::current()->PostTask( | 46 MessageLoop::current()->PostTask( |
| 46 FROM_HERE, NewRunnableMethod(this, | 47 FROM_HERE, NewRunnableMethod(this, |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 LOG(INFO) << "SpdyStream: Data (" << length << " bytes) received for " | 177 LOG(INFO) << "SpdyStream: Data (" << length << " bytes) received for " |
| 177 << stream_id_; | 178 << stream_id_; |
| 178 | 179 |
| 179 if (!delegate_ || continue_buffering_data_) { | 180 if (!delegate_ || continue_buffering_data_) { |
| 180 // It should be valid for this to happen in the server push case. | 181 // It should be valid for this to happen in the server push case. |
| 181 // We'll return received data when delegate gets attached to the stream. | 182 // We'll return received data when delegate gets attached to the stream. |
| 182 if (length > 0) { | 183 if (length > 0) { |
| 183 IOBufferWithSize* buf = new IOBufferWithSize(length); | 184 IOBufferWithSize* buf = new IOBufferWithSize(length); |
| 184 memcpy(buf->data(), data, length); | 185 memcpy(buf->data(), data, length); |
| 185 pending_buffers_.push_back(buf); | 186 pending_buffers_.push_back(buf); |
| 187 } else { |
| 188 pending_buffers_.push_back(NULL); |
| 189 metrics_.StopStream(); |
| 190 session_->CloseStream(stream_id_, net::OK); |
| 191 // Note: |this| may be deleted after calling CloseStream. |
| 186 } | 192 } |
| 187 else | |
| 188 pending_buffers_.push_back(NULL); | |
| 189 return; | 193 return; |
| 190 } | 194 } |
| 191 | 195 |
| 192 CHECK(!closed()); | 196 CHECK(!closed()); |
| 193 | 197 |
| 194 // If we don't have a response, then the SYN_REPLY did not come through. | 198 // If we don't have a response, then the SYN_REPLY did not come through. |
| 195 // We cannot pass data up to the caller unless the reply headers have been | 199 // We cannot pass data up to the caller unless the reply headers have been |
| 196 // received. | 200 // received. |
| 197 if (!response_received()) { | 201 if (!response_received()) { |
| 198 session_->CloseStream(stream_id_, ERR_SYN_REPLY_NOT_RECEIVED); | 202 session_->CloseStream(stream_id_, ERR_SYN_REPLY_NOT_RECEIVED); |
| 199 return; | 203 return; |
| 200 } | 204 } |
| 201 | 205 |
| 202 // A zero-length read means that the stream is being closed. | 206 // A zero-length read means that the stream is being closed. |
| 203 if (!length) { | 207 if (!length) { |
| 204 metrics_.StopStream(); | 208 metrics_.StopStream(); |
| 205 scoped_refptr<SpdyStream> self(this); | |
| 206 session_->CloseStream(stream_id_, net::OK); | 209 session_->CloseStream(stream_id_, net::OK); |
| 207 UpdateHistograms(); | 210 // Note: |this| may be deleted after calling CloseStream. |
| 208 return; | 211 return; |
| 209 } | 212 } |
| 210 | 213 |
| 211 // Track our bandwidth. | 214 // Track our bandwidth. |
| 212 metrics_.RecordBytes(length); | 215 metrics_.RecordBytes(length); |
| 213 recv_bytes_ += length; | 216 recv_bytes_ += length; |
| 214 recv_last_byte_time_ = base::TimeTicks::Now(); | 217 recv_last_byte_time_ = base::TimeTicks::Now(); |
| 215 | 218 |
| 216 if (!delegate_) { | 219 if (!delegate_) { |
| 217 // It should be valid for this to happen in the server push case. | 220 // It should be valid for this to happen in the server push case. |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 } | 415 } |
| 413 | 416 |
| 414 int SpdyStream::DoOpen(int result) { | 417 int SpdyStream::DoOpen(int result) { |
| 415 if (delegate_) | 418 if (delegate_) |
| 416 delegate_->OnDataSent(result); | 419 delegate_->OnDataSent(result); |
| 417 io_state_ = STATE_OPEN; | 420 io_state_ = STATE_OPEN; |
| 418 return result; | 421 return result; |
| 419 } | 422 } |
| 420 | 423 |
| 421 void SpdyStream::UpdateHistograms() { | 424 void SpdyStream::UpdateHistograms() { |
| 422 if (histograms_recorded_) | |
| 423 return; | |
| 424 | |
| 425 histograms_recorded_ = true; | |
| 426 | |
| 427 // We need all timers to be filled in, otherwise metrics can be bogus. | 425 // We need all timers to be filled in, otherwise metrics can be bogus. |
| 428 if (send_time_.is_null() || recv_first_byte_time_.is_null() || | 426 if (send_time_.is_null() || recv_first_byte_time_.is_null() || |
| 429 recv_last_byte_time_.is_null()) | 427 recv_last_byte_time_.is_null()) |
| 430 return; | 428 return; |
| 431 | 429 |
| 432 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTimeToFirstByte", | 430 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTimeToFirstByte", |
| 433 recv_first_byte_time_ - send_time_); | 431 recv_first_byte_time_ - send_time_); |
| 434 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime", | 432 UMA_HISTOGRAM_TIMES("Net.SpdyStreamDownloadTime", |
| 435 recv_last_byte_time_ - recv_first_byte_time_); | 433 recv_last_byte_time_ - recv_first_byte_time_); |
| 436 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", | 434 UMA_HISTOGRAM_TIMES("Net.SpdyStreamTime", |
| 437 recv_last_byte_time_ - send_time_); | 435 recv_last_byte_time_ - send_time_); |
| 438 | 436 |
| 439 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); | 437 UMA_HISTOGRAM_COUNTS("Net.SpdySendBytes", send_bytes_); |
| 440 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); | 438 UMA_HISTOGRAM_COUNTS("Net.SpdyRecvBytes", recv_bytes_); |
| 441 } | 439 } |
| 442 | 440 |
| 443 } // namespace net | 441 } // namespace net |
| OLD | NEW |