Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: net/spdy/spdy_session.cc

Issue 13834009: SPDY - Re-land greedy read support for SpdySession (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Two new histograms for total bytes read Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_session_spdy2_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/message_loop.h" 14 #include "base/message_loop.h"
15 #include "base/metrics/field_trial.h" 15 #include "base/metrics/field_trial.h"
16 #include "base/metrics/histogram.h" 16 #include "base/metrics/histogram.h"
17 #include "base/metrics/sparse_histogram.h"
17 #include "base/metrics/stats_counters.h" 18 #include "base/metrics/stats_counters.h"
18 #include "base/stl_util.h" 19 #include "base/stl_util.h"
19 #include "base/string_number_conversions.h" 20 #include "base/string_number_conversions.h"
20 #include "base/string_util.h" 21 #include "base/string_util.h"
21 #include "base/stringprintf.h" 22 #include "base/stringprintf.h"
22 #include "base/time.h" 23 #include "base/time.h"
23 #include "base/utf_string_conversions.h" 24 #include "base/utf_string_conversions.h"
24 #include "base/values.h" 25 #include "base/values.h"
25 #include "crypto/ec_private_key.h" 26 #include "crypto/ec_private_key.h"
26 #include "crypto/ec_signature_creator.h" 27 #include "crypto/ec_signature_creator.h"
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 size_t max_concurrent_streams_limit, 323 size_t max_concurrent_streams_limit,
323 TimeFunc time_func, 324 TimeFunc time_func,
324 const HostPortPair& trusted_spdy_proxy, 325 const HostPortPair& trusted_spdy_proxy,
325 NetLog* net_log) 326 NetLog* net_log)
326 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), 327 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
327 host_port_proxy_pair_(host_port_proxy_pair), 328 host_port_proxy_pair_(host_port_proxy_pair),
328 spdy_session_pool_(spdy_session_pool), 329 spdy_session_pool_(spdy_session_pool),
329 http_server_properties_(http_server_properties), 330 http_server_properties_(http_server_properties),
330 connection_(new ClientSocketHandle), 331 connection_(new ClientSocketHandle),
331 read_buffer_(new IOBuffer(kReadBufferSize)), 332 read_buffer_(new IOBuffer(kReadBufferSize)),
332 read_pending_(false),
333 stream_hi_water_mark_(kFirstStreamId), 333 stream_hi_water_mark_(kFirstStreamId),
334 write_pending_(false), 334 write_pending_(false),
335 delayed_write_pending_(false), 335 delayed_write_pending_(false),
336 is_secure_(false), 336 is_secure_(false),
337 certificate_error_code_(OK), 337 certificate_error_code_(OK),
338 error_(OK), 338 error_(OK),
339 state_(IDLE), 339 state_(STATE_IDLE),
340 max_concurrent_streams_(initial_max_concurrent_streams == 0 ? 340 max_concurrent_streams_(initial_max_concurrent_streams == 0 ?
341 kInitialMaxConcurrentStreams : 341 kInitialMaxConcurrentStreams :
342 initial_max_concurrent_streams), 342 initial_max_concurrent_streams),
343 max_concurrent_streams_limit_(max_concurrent_streams_limit == 0 ? 343 max_concurrent_streams_limit_(max_concurrent_streams_limit == 0 ?
344 kMaxConcurrentStreamLimit : 344 kMaxConcurrentStreamLimit :
345 max_concurrent_streams_limit), 345 max_concurrent_streams_limit),
346 streams_initiated_count_(0), 346 streams_initiated_count_(0),
347 streams_pushed_count_(0), 347 streams_pushed_count_(0),
348 streams_pushed_and_claimed_count_(0), 348 streams_pushed_and_claimed_count_(0),
349 streams_abandoned_count_(0), 349 streams_abandoned_count_(0),
350 bytes_received_(0), 350 total_bytes_received_(0),
351 bytes_read_(0),
351 sent_settings_(false), 352 sent_settings_(false),
352 received_settings_(false), 353 received_settings_(false),
353 stalled_streams_(0), 354 stalled_streams_(0),
354 pings_in_flight_(0), 355 pings_in_flight_(0),
355 next_ping_id_(1), 356 next_ping_id_(1),
356 last_activity_time_(base::TimeTicks::Now()), 357 last_activity_time_(base::TimeTicks::Now()),
357 check_ping_status_pending_(false), 358 check_ping_status_pending_(false),
358 flow_control_state_(FLOW_CONTROL_NONE), 359 flow_control_state_(FLOW_CONTROL_NONE),
359 stream_initial_send_window_size_(kSpdyStreamInitialWindowSize), 360 stream_initial_send_window_size_(kSpdyStreamInitialWindowSize),
360 stream_initial_recv_window_size_(stream_initial_recv_window_size == 0 ? 361 stream_initial_recv_window_size_(stream_initial_recv_window_size == 0 ?
(...skipping 20 matching lines...) Expand all
381 DCHECK(HttpStreamFactory::spdy_enabled()); 382 DCHECK(HttpStreamFactory::spdy_enabled());
382 net_log_.BeginEvent( 383 net_log_.BeginEvent(
383 NetLog::TYPE_SPDY_SESSION, 384 NetLog::TYPE_SPDY_SESSION,
384 base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair_)); 385 base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair_));
385 next_unclaimed_push_stream_sweep_time_ = time_func_() + 386 next_unclaimed_push_stream_sweep_time_ = time_func_() +
386 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); 387 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds);
387 // TODO(mbelshe): consider randomization of the stream_hi_water_mark. 388 // TODO(mbelshe): consider randomization of the stream_hi_water_mark.
388 } 389 }
389 390
390 SpdySession::~SpdySession() { 391 SpdySession::~SpdySession() {
391 if (state_ != CLOSED) { 392 if (state_ != STATE_CLOSED) {
392 state_ = CLOSED; 393 state_ = STATE_CLOSED;
393 394
394 // Cleanup all the streams. 395 // Cleanup all the streams.
395 CloseAllStreams(net::ERR_ABORTED); 396 CloseAllStreams(net::ERR_ABORTED);
396 } 397 }
397 398
398 if (connection_->is_initialized()) { 399 if (connection_->is_initialized()) {
399 // With SPDY we can't recycle sockets. 400 // With SPDY we can't recycle sockets.
400 connection_->socket()->Disconnect(); 401 connection_->socket()->Disconnect();
401 } 402 }
402 403
(...skipping 11 matching lines...) Expand all
414 net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION); 415 net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION);
415 } 416 }
416 417
417 net::Error SpdySession::InitializeWithSocket( 418 net::Error SpdySession::InitializeWithSocket(
418 ClientSocketHandle* connection, 419 ClientSocketHandle* connection,
419 bool is_secure, 420 bool is_secure,
420 int certificate_error_code) { 421 int certificate_error_code) {
421 base::StatsCounter spdy_sessions("spdy.sessions"); 422 base::StatsCounter spdy_sessions("spdy.sessions");
422 spdy_sessions.Increment(); 423 spdy_sessions.Increment();
423 424
424 state_ = CONNECTED; 425 state_ = STATE_DO_READ;
425 connection_.reset(connection); 426 connection_.reset(connection);
426 is_secure_ = is_secure; 427 is_secure_ = is_secure;
427 certificate_error_code_ = certificate_error_code; 428 certificate_error_code_ = certificate_error_code;
428 429
429 NextProto protocol = default_protocol_; 430 NextProto protocol = default_protocol_;
430 NextProto protocol_negotiated = connection->socket()->GetNegotiatedProtocol(); 431 NextProto protocol_negotiated = connection->socket()->GetNegotiatedProtocol();
431 if (protocol_negotiated != kProtoUnknown) { 432 if (protocol_negotiated != kProtoUnknown) {
432 protocol = protocol_negotiated; 433 protocol = protocol_negotiated;
433 } 434 }
434 435
(...skipping 30 matching lines...) Expand all
465 DCHECK_GT(kDefaultInitialRecvWindowSize, session_recv_window_size_); 466 DCHECK_GT(kDefaultInitialRecvWindowSize, session_recv_window_size_);
466 // This condition implies that |kDefaultInitialRecvWindowSize| - 467 // This condition implies that |kDefaultInitialRecvWindowSize| -
467 // |session_recv_window_size_| doesn't overflow. 468 // |session_recv_window_size_| doesn't overflow.
468 DCHECK_GT(session_recv_window_size_, 0); 469 DCHECK_GT(session_recv_window_size_, 0);
469 IncreaseRecvWindowSize( 470 IncreaseRecvWindowSize(
470 kDefaultInitialRecvWindowSize - session_recv_window_size_); 471 kDefaultInitialRecvWindowSize - session_recv_window_size_);
471 } 472 }
472 473
473 // Write out any data that we might have to send, such as the settings frame. 474 // Write out any data that we might have to send, such as the settings frame.
474 WriteSocketLater(); 475 WriteSocketLater();
475 net::Error error = ReadSocket(); 476 int error = DoLoop(OK);
476 if (error == ERR_IO_PENDING) 477 if (error == ERR_IO_PENDING)
477 return OK; 478 return OK;
478 return error; 479 return static_cast<net::Error>(error);
479 } 480 }
480 481
481 bool SpdySession::VerifyDomainAuthentication(const std::string& domain) { 482 bool SpdySession::VerifyDomainAuthentication(const std::string& domain) {
482 if (!verify_domain_authentication_) 483 if (!verify_domain_authentication_)
483 return true; 484 return true;
484 485
485 if (state_ != CONNECTED) 486 if (!IsConnected())
486 return false; 487 return false;
487 488
488 SSLInfo ssl_info; 489 SSLInfo ssl_info;
489 bool was_npn_negotiated; 490 bool was_npn_negotiated;
490 NextProto protocol_negotiated = kProtoUnknown; 491 NextProto protocol_negotiated = kProtoUnknown;
491 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated)) 492 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated))
492 return true; // This is not a secure session, so all domains are okay. 493 return true; // This is not a secure session, so all domains are okay.
493 494
494 return !ssl_info.client_cert_sent && 495 return !ssl_info.client_cert_sent &&
495 (enable_credential_frames_ || !ssl_info.channel_id_sent || 496 (enable_credential_frames_ || !ssl_info.channel_id_sent ||
496 ServerBoundCertService::GetDomainForHost(domain) == 497 ServerBoundCertService::GetDomainForHost(domain) ==
497 ServerBoundCertService::GetDomainForHost( 498 ServerBoundCertService::GetDomainForHost(
498 host_port_proxy_pair_.first.host())) && 499 host_port_proxy_pair_.first.host())) &&
499 ssl_info.cert->VerifyNameMatch(domain); 500 ssl_info.cert->VerifyNameMatch(domain);
500 } 501 }
501 502
502 void SpdySession::SetStreamHasWriteAvailable(SpdyStream* stream, 503 void SpdySession::SetStreamHasWriteAvailable(SpdyStream* stream,
503 SpdyIOBufferProducer* producer) { 504 SpdyIOBufferProducer* producer) {
504 write_queue_.push(producer); 505 write_queue_.push(producer);
505 stream_producers_[producer] = stream; 506 stream_producers_[producer] = stream;
506 WriteSocketLater(); 507 WriteSocketLater();
507 } 508 }
508 509
509 int SpdySession::GetPushStream( 510 int SpdySession::GetPushStream(
510 const GURL& url, 511 const GURL& url,
511 scoped_refptr<SpdyStream>* stream, 512 scoped_refptr<SpdyStream>* stream,
512 const BoundNetLog& stream_net_log) { 513 const BoundNetLog& stream_net_log) {
513 CHECK_NE(state_, CLOSED); 514 CHECK_NE(state_, STATE_CLOSED);
514 515
515 *stream = NULL; 516 *stream = NULL;
516 517
517 // Don't allow access to secure push streams over an unauthenticated, but 518 // Don't allow access to secure push streams over an unauthenticated, but
518 // encrypted SSL socket. 519 // encrypted SSL socket.
519 if (is_secure_ && certificate_error_code_ != OK && 520 if (is_secure_ && certificate_error_code_ != OK &&
520 (url.SchemeIs("https") || url.SchemeIs("wss"))) { 521 (url.SchemeIs("https") || url.SchemeIs("wss"))) {
521 RecordProtocolErrorHistogram( 522 RecordProtocolErrorHistogram(
522 PROTOCOL_ERROR_REQUEST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION); 523 PROTOCOL_ERROR_REQUEST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION);
523 CloseSessionOnError( 524 CloseSessionOnError(
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 return ContainsKey(active_streams_, stream_id); 874 return ContainsKey(active_streams_, stream_id);
874 } 875 }
875 876
876 LoadState SpdySession::GetLoadState() const { 877 LoadState SpdySession::GetLoadState() const {
877 // NOTE: The application only queries the LoadState via the 878 // NOTE: The application only queries the LoadState via the
878 // SpdyNetworkTransaction, and details are only needed when 879 // SpdyNetworkTransaction, and details are only needed when
879 // we're in the process of connecting. 880 // we're in the process of connecting.
880 881
881 // If we're connecting, defer to the connection to give us the actual 882 // If we're connecting, defer to the connection to give us the actual
882 // LoadState. 883 // LoadState.
883 if (state_ == CONNECTING) 884 if (state_ == STATE_CONNECTING)
884 return connection_->GetLoadState(); 885 return connection_->GetLoadState();
885 886
886 // Just report that we're idle since the session could be doing 887 // Just report that we're idle since the session could be doing
887 // many things concurrently. 888 // many things concurrently.
888 return LOAD_STATE_IDLE; 889 return LOAD_STATE_IDLE;
889 } 890 }
890 891
891 void SpdySession::OnReadComplete(int bytes_read) { 892 void SpdySession::OnReadComplete(int bytes_read) {
892 // Parse a frame. For now this code requires that the frame fit into our 893 DCHECK_NE(state_, STATE_DO_READ);
893 // buffer (32KB). 894 DoLoop(bytes_read);
894 // TODO(mbelshe): support arbitrarily large frames! 895 }
895 896
896 read_pending_ = false; 897 void SpdySession::StartRead() {
898 DCHECK_NE(state_, STATE_DO_READ_COMPLETE);
899 DoLoop(OK);
900 }
897 901
898 if (bytes_read <= 0) { 902 int SpdySession::DoLoop(int result) {
899 // Session is tearing down. 903 bytes_read_ = 0;
900 net::Error error = static_cast<net::Error>(bytes_read);
901 if (bytes_read == 0)
902 error = ERR_CONNECTION_CLOSED;
903 CloseSessionOnError(error, true, "bytes_read is <= 0.");
904 return;
905 }
906
907 bytes_received_ += bytes_read;
908
909 last_activity_time_ = base::TimeTicks::Now();
910 904
911 // The SpdyFramer will use callbacks onto |this| as it parses frames. 905 // The SpdyFramer will use callbacks onto |this| as it parses frames.
912 // When errors occur, those callbacks can lead to teardown of all references 906 // When errors occur, those callbacks can lead to teardown of all references
913 // to |this|, so maintain a reference to self during this call for safe 907 // to |this|, so maintain a reference to self during this call for safe
914 // cleanup. 908 // cleanup.
915 scoped_refptr<SpdySession> self(this); 909 scoped_refptr<SpdySession> self(this);
916 910
911 do {
912 switch (state_) {
913 case STATE_DO_READ:
914 DCHECK_EQ(result, OK);
915 result = DoRead();
916 break;
917 case STATE_DO_READ_COMPLETE:
918 result = DoReadComplete(result);
919 break;
920 case STATE_CLOSED:
921 result = ERR_CONNECTION_CLOSED;
922 break;
923 default:
924 NOTREACHED() << "state_: " << state_;
925 break;
926 }
927 } while (result != ERR_IO_PENDING && state_ != STATE_CLOSED);
928
929 return result;
930 }
931
932 int SpdySession::DoRead() {
933 if (bytes_read_ > kMaxReadBytes) {
934 state_ = STATE_DO_READ;
935 MessageLoop::current()->PostTask(
936 FROM_HERE,
937 base::Bind(&SpdySession::StartRead,
938 weak_factory_.GetWeakPtr()));
939 return ERR_IO_PENDING;
940 }
941
942 CHECK(connection_.get());
943 CHECK(connection_->socket());
944 state_ = STATE_DO_READ_COMPLETE;
945 return connection_->socket()->Read(
946 read_buffer_.get(),
947 kReadBufferSize,
948 base::Bind(&SpdySession::OnReadComplete, weak_factory_.GetWeakPtr()));
949 }
950
951 int SpdySession::DoReadComplete(int result) {
952 // Parse a frame. For now this code requires that the frame fit into our
953 // buffer (32KB).
954 // TODO(mbelshe): support arbitrarily large frames!
955
956 if (result <= 0) {
957 // Session is tearing down.
958 net::Error error = static_cast<net::Error>(result);
959 if (result == 0) {
960 UMA_HISTOGRAM_COUNTS("Net.SpdySession.BytesRead.EOF",
961 total_bytes_received_);
962 error = ERR_CONNECTION_CLOSED;
963 }
964 CloseSessionOnError(error, true, "result is <= 0.");
965 return ERR_CONNECTION_CLOSED;
966 }
967
968 total_bytes_received_ += result;
969 bytes_read_ += result;
970
971 last_activity_time_ = base::TimeTicks::Now();
972
917 DCHECK(buffered_spdy_framer_.get()); 973 DCHECK(buffered_spdy_framer_.get());
918 char* data = read_buffer_->data(); 974 char* data = read_buffer_->data();
919 while (bytes_read && 975 while (result &&
920 buffered_spdy_framer_->error_code() == 976 buffered_spdy_framer_->error_code() ==
921 SpdyFramer::SPDY_NO_ERROR) { 977 SpdyFramer::SPDY_NO_ERROR) {
922 uint32 bytes_processed = 978 uint32 bytes_processed =
923 buffered_spdy_framer_->ProcessInput(data, bytes_read); 979 buffered_spdy_framer_->ProcessInput(data, result);
924 bytes_read -= bytes_processed; 980 result -= bytes_processed;
925 data += bytes_processed; 981 data += bytes_processed;
926 } 982 }
927 983
928 if (state_ != CLOSED) 984 if (IsConnected())
929 ReadSocket(); 985 state_ = STATE_DO_READ;
986 return OK;
930 } 987 }
931 988
932 void SpdySession::OnWriteComplete(int result) { 989 void SpdySession::OnWriteComplete(int result) {
933 DCHECK(write_pending_); 990 DCHECK(write_pending_);
934 DCHECK(in_flight_write_.size()); 991 DCHECK(in_flight_write_.size());
935 992
936 last_activity_time_ = base::TimeTicks::Now(); 993 last_activity_time_ = base::TimeTicks::Now();
937 write_pending_ = false; 994 write_pending_ = false;
938 995
939 scoped_refptr<SpdyStream> stream = in_flight_write_.stream(); 996 scoped_refptr<SpdyStream> stream = in_flight_write_.stream();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 WriteSocketLater(); 1033 WriteSocketLater();
977 } else { 1034 } else {
978 in_flight_write_.release(); 1035 in_flight_write_.release();
979 1036
980 // The stream is now errored. Close it down. 1037 // The stream is now errored. Close it down.
981 CloseSessionOnError( 1038 CloseSessionOnError(
982 static_cast<net::Error>(result), true, "The stream has errored."); 1039 static_cast<net::Error>(result), true, "The stream has errored.");
983 } 1040 }
984 } 1041 }
985 1042
986 net::Error SpdySession::ReadSocket() {
987 if (read_pending_)
988 return OK;
989
990 if (state_ == CLOSED) {
991 NOTREACHED();
992 return ERR_UNEXPECTED;
993 }
994
995 CHECK(connection_.get());
996 CHECK(connection_->socket());
997 int bytes_read = connection_->socket()->Read(
998 read_buffer_.get(),
999 kReadBufferSize,
1000 base::Bind(&SpdySession::OnReadComplete, base::Unretained(this)));
1001 switch (bytes_read) {
1002 case 0:
1003 // Socket is closed!
1004 CloseSessionOnError(ERR_CONNECTION_CLOSED, true, "bytes_read is 0.");
1005 return ERR_CONNECTION_CLOSED;
1006 case net::ERR_IO_PENDING:
1007 // Waiting for data. Nothing to do now.
1008 read_pending_ = true;
1009 return ERR_IO_PENDING;
1010 default:
1011 // Data was read, process it.
1012 // Schedule the work through the message loop to avoid recursive
1013 // callbacks.
1014 read_pending_ = true;
1015 MessageLoop::current()->PostTask(
1016 FROM_HERE,
1017 base::Bind(&SpdySession::OnReadComplete,
1018 weak_factory_.GetWeakPtr(), bytes_read));
1019 break;
1020 }
1021 return OK;
1022 }
1023
1024 void SpdySession::WriteSocketLater() { 1043 void SpdySession::WriteSocketLater() {
1025 if (delayed_write_pending_) 1044 if (delayed_write_pending_)
1026 return; 1045 return;
1027 1046
1028 if (state_ < CONNECTED) 1047 if (!IsConnected())
1029 return; 1048 return;
1030 1049
1031 delayed_write_pending_ = true; 1050 delayed_write_pending_ = true;
1032 MessageLoop::current()->PostTask( 1051 MessageLoop::current()->PostTask(
1033 FROM_HERE, 1052 FROM_HERE,
1034 base::Bind(&SpdySession::WriteSocket, weak_factory_.GetWeakPtr())); 1053 base::Bind(&SpdySession::WriteSocket, weak_factory_.GetWeakPtr()));
1035 } 1054 }
1036 1055
1037 void SpdySession::WriteSocket() { 1056 void SpdySession::WriteSocket() {
1038 // This function should only be called via WriteSocketLater. 1057 // This function should only be called via WriteSocketLater.
1039 DCHECK(delayed_write_pending_); 1058 DCHECK(delayed_write_pending_);
1040 delayed_write_pending_ = false; 1059 delayed_write_pending_ = false;
1041 1060
1042 // If the socket isn't connected yet, just wait; we'll get called 1061 // If the socket isn't connected yet, just wait; we'll get called
1043 // again when the socket connection completes. If the socket is 1062 // again when the socket connection completes. If the socket is
1044 // closed, just return. 1063 // closed, just return.
1045 if (state_ < CONNECTED || state_ == CLOSED) 1064 if (!IsConnected())
1046 return; 1065 return;
1047 1066
1048 if (write_pending_) // Another write is in progress still. 1067 if (write_pending_) // Another write is in progress still.
1049 return; 1068 return;
1050 1069
1051 // Loop sending frames until we've sent everything or until the write 1070 // Loop sending frames until we've sent everything or until the write
1052 // returns error (or ERR_IO_PENDING). 1071 // returns error (or ERR_IO_PENDING).
1053 DCHECK(buffered_spdy_framer_.get()); 1072 DCHECK(buffered_spdy_framer_.get());
1054 while (in_flight_write_.buffer() || !write_queue_.empty()) { 1073 while (in_flight_write_.buffer() || !write_queue_.empty()) {
1055 if (!in_flight_write_.buffer()) { 1074 if (!in_flight_write_.buffer()) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 scoped_refptr<SpdySession> self(this); 1177 scoped_refptr<SpdySession> self(this);
1159 1178
1160 DCHECK_LT(err, OK); 1179 DCHECK_LT(err, OK);
1161 net_log_.AddEvent( 1180 net_log_.AddEvent(
1162 NetLog::TYPE_SPDY_SESSION_CLOSE, 1181 NetLog::TYPE_SPDY_SESSION_CLOSE,
1163 base::Bind(&NetLogSpdySessionCloseCallback, err, &description)); 1182 base::Bind(&NetLogSpdySessionCloseCallback, err, &description));
1164 1183
1165 // Don't close twice. This can occur because we can have both 1184 // Don't close twice. This can occur because we can have both
1166 // a read and a write outstanding, and each can complete with 1185 // a read and a write outstanding, and each can complete with
1167 // an error. 1186 // an error.
1168 if (state_ != CLOSED) { 1187 if (!IsClosed()) {
1169 state_ = CLOSED; 1188 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SpdySession.ClosedOnError.Error", -err);
Ryan Hamilton 2013/04/16 19:54:47 jar: how slowly is slowly?
Ryan Hamilton 2013/04/16 19:54:47 nit: I think I would drop the trailing .Error sinc
ramant (doing other things) 2013/04/16 21:45:15 Done.
1189 UMA_HISTOGRAM_COUNTS("Net.SpdySession.BytesRead.OtherErrors",
1190 total_bytes_received_);
1191 state_ = STATE_CLOSED;
1170 error_ = err; 1192 error_ = err;
1171 if (remove_from_pool) 1193 if (remove_from_pool)
1172 RemoveFromPool(); 1194 RemoveFromPool();
1173 CloseAllStreams(err); 1195 CloseAllStreams(err);
1174 } 1196 }
1175 } 1197 }
1176 1198
1177 base::Value* SpdySession::GetInfoAsValue() const { 1199 base::Value* SpdySession::GetInfoAsValue() const {
1178 base::DictionaryValue* dict = new base::DictionaryValue(); 1200 base::DictionaryValue* dict = new base::DictionaryValue();
1179 1201
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after
2116 SettingsMap::const_iterator it; 2138 SettingsMap::const_iterator it;
2117 for (it = settings_map.begin(); it != settings_map.end(); ++it) { 2139 for (it = settings_map.begin(); it != settings_map.end(); ++it) {
2118 const SpdySettingsIds id = it->first; 2140 const SpdySettingsIds id = it->first;
2119 const uint32 val = it->second.second; 2141 const uint32 val = it->second.second;
2120 switch (id) { 2142 switch (id) {
2121 case SETTINGS_CURRENT_CWND: 2143 case SETTINGS_CURRENT_CWND:
2122 // Record several different histograms to see if cwnd converges 2144 // Record several different histograms to see if cwnd converges
2123 // for larger volumes of data being sent. 2145 // for larger volumes of data being sent.
2124 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd", 2146 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd",
2125 val, 1, 200, 100); 2147 val, 1, 200, 100);
2126 if (bytes_received_ > 10 * 1024) { 2148 if (total_bytes_received_ > 10 * 1024) {
2127 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd10K", 2149 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd10K",
2128 val, 1, 200, 100); 2150 val, 1, 200, 100);
2129 if (bytes_received_ > 25 * 1024) { 2151 if (total_bytes_received_ > 25 * 1024) {
2130 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd25K", 2152 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd25K",
2131 val, 1, 200, 100); 2153 val, 1, 200, 100);
2132 if (bytes_received_ > 50 * 1024) { 2154 if (total_bytes_received_ > 50 * 1024) {
2133 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd50K", 2155 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd50K",
2134 val, 1, 200, 100); 2156 val, 1, 200, 100);
2135 if (bytes_received_ > 100 * 1024) { 2157 if (total_bytes_received_ > 100 * 1024) {
2136 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd100K", 2158 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd100K",
2137 val, 1, 200, 100); 2159 val, 1, 200, 100);
2138 } 2160 }
2139 } 2161 }
2140 } 2162 }
2141 } 2163 }
2142 break; 2164 break;
2143 case SETTINGS_ROUND_TRIP_TIME: 2165 case SETTINGS_ROUND_TRIP_TIME:
2144 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRTT", 2166 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRTT",
2145 val, 1, 1200, 100); 2167 val, 1, 1200, 100);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
2304 } 2326 }
2305 2327
2306 session_recv_window_size_ -= delta_window_size; 2328 session_recv_window_size_ -= delta_window_size;
2307 net_log_.AddEvent( 2329 net_log_.AddEvent(
2308 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, 2330 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW,
2309 base::Bind(&NetLogSpdySessionWindowUpdateCallback, 2331 base::Bind(&NetLogSpdySessionWindowUpdateCallback,
2310 -delta_window_size, session_recv_window_size_)); 2332 -delta_window_size, session_recv_window_size_));
2311 } 2333 }
2312 2334
2313 } // namespace net 2335 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_session.h ('k') | net/spdy/spdy_session_spdy2_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698