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 |