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

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: Merging changes from tip 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 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 size_t max_concurrent_streams_limit, 302 size_t max_concurrent_streams_limit,
302 TimeFunc time_func, 303 TimeFunc time_func,
303 const HostPortPair& trusted_spdy_proxy, 304 const HostPortPair& trusted_spdy_proxy,
304 NetLog* net_log) 305 NetLog* net_log)
305 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), 306 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
306 host_port_proxy_pair_(host_port_proxy_pair), 307 host_port_proxy_pair_(host_port_proxy_pair),
307 spdy_session_pool_(spdy_session_pool), 308 spdy_session_pool_(spdy_session_pool),
308 http_server_properties_(http_server_properties), 309 http_server_properties_(http_server_properties),
309 connection_(new ClientSocketHandle), 310 connection_(new ClientSocketHandle),
310 read_buffer_(new IOBuffer(kReadBufferSize)), 311 read_buffer_(new IOBuffer(kReadBufferSize)),
311 read_pending_(false),
312 stream_hi_water_mark_(kFirstStreamId), 312 stream_hi_water_mark_(kFirstStreamId),
313 write_pending_(false), 313 write_pending_(false),
314 in_flight_write_frame_type_(DATA), 314 in_flight_write_frame_type_(DATA),
315 delayed_write_pending_(false), 315 delayed_write_pending_(false),
316 is_secure_(false), 316 is_secure_(false),
317 certificate_error_code_(OK), 317 certificate_error_code_(OK),
318 error_(OK), 318 error_(OK),
319 state_(IDLE), 319 state_(STATE_IDLE),
320 max_concurrent_streams_(initial_max_concurrent_streams == 0 ? 320 max_concurrent_streams_(initial_max_concurrent_streams == 0 ?
321 kInitialMaxConcurrentStreams : 321 kInitialMaxConcurrentStreams :
322 initial_max_concurrent_streams), 322 initial_max_concurrent_streams),
323 max_concurrent_streams_limit_(max_concurrent_streams_limit == 0 ? 323 max_concurrent_streams_limit_(max_concurrent_streams_limit == 0 ?
324 kMaxConcurrentStreamLimit : 324 kMaxConcurrentStreamLimit :
325 max_concurrent_streams_limit), 325 max_concurrent_streams_limit),
326 streams_initiated_count_(0), 326 streams_initiated_count_(0),
327 streams_pushed_count_(0), 327 streams_pushed_count_(0),
328 streams_pushed_and_claimed_count_(0), 328 streams_pushed_and_claimed_count_(0),
329 streams_abandoned_count_(0), 329 streams_abandoned_count_(0),
330 bytes_received_(0), 330 total_bytes_received_(0),
331 bytes_read_(0),
331 sent_settings_(false), 332 sent_settings_(false),
332 received_settings_(false), 333 received_settings_(false),
333 stalled_streams_(0), 334 stalled_streams_(0),
334 pings_in_flight_(0), 335 pings_in_flight_(0),
335 next_ping_id_(1), 336 next_ping_id_(1),
336 last_activity_time_(base::TimeTicks::Now()), 337 last_activity_time_(base::TimeTicks::Now()),
337 check_ping_status_pending_(false), 338 check_ping_status_pending_(false),
338 flow_control_state_(FLOW_CONTROL_NONE), 339 flow_control_state_(FLOW_CONTROL_NONE),
339 stream_initial_send_window_size_(kSpdyStreamInitialWindowSize), 340 stream_initial_send_window_size_(kSpdyStreamInitialWindowSize),
340 stream_initial_recv_window_size_(stream_initial_recv_window_size == 0 ? 341 stream_initial_recv_window_size_(stream_initial_recv_window_size == 0 ?
(...skipping 20 matching lines...) Expand all
361 DCHECK(HttpStreamFactory::spdy_enabled()); 362 DCHECK(HttpStreamFactory::spdy_enabled());
362 net_log_.BeginEvent( 363 net_log_.BeginEvent(
363 NetLog::TYPE_SPDY_SESSION, 364 NetLog::TYPE_SPDY_SESSION,
364 base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair_)); 365 base::Bind(&NetLogSpdySessionCallback, &host_port_proxy_pair_));
365 next_unclaimed_push_stream_sweep_time_ = time_func_() + 366 next_unclaimed_push_stream_sweep_time_ = time_func_() +
366 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds); 367 base::TimeDelta::FromSeconds(kMinPushedStreamLifetimeSeconds);
367 // TODO(mbelshe): consider randomization of the stream_hi_water_mark. 368 // TODO(mbelshe): consider randomization of the stream_hi_water_mark.
368 } 369 }
369 370
370 SpdySession::~SpdySession() { 371 SpdySession::~SpdySession() {
371 if (state_ != CLOSED) { 372 if (state_ != STATE_CLOSED) {
372 state_ = CLOSED; 373 state_ = STATE_CLOSED;
373 374
374 // Cleanup all the streams. 375 // Cleanup all the streams.
375 CloseAllStreams(net::ERR_ABORTED); 376 CloseAllStreams(net::ERR_ABORTED);
376 } 377 }
377 378
378 if (connection_->is_initialized()) { 379 if (connection_->is_initialized()) {
379 // With SPDY we can't recycle sockets. 380 // With SPDY we can't recycle sockets.
380 connection_->socket()->Disconnect(); 381 connection_->socket()->Disconnect();
381 } 382 }
382 383
(...skipping 11 matching lines...) Expand all
394 net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION); 395 net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION);
395 } 396 }
396 397
397 net::Error SpdySession::InitializeWithSocket( 398 net::Error SpdySession::InitializeWithSocket(
398 ClientSocketHandle* connection, 399 ClientSocketHandle* connection,
399 bool is_secure, 400 bool is_secure,
400 int certificate_error_code) { 401 int certificate_error_code) {
401 base::StatsCounter spdy_sessions("spdy.sessions"); 402 base::StatsCounter spdy_sessions("spdy.sessions");
402 spdy_sessions.Increment(); 403 spdy_sessions.Increment();
403 404
404 state_ = CONNECTED; 405 state_ = STATE_DO_READ;
405 connection_.reset(connection); 406 connection_.reset(connection);
406 is_secure_ = is_secure; 407 is_secure_ = is_secure;
407 certificate_error_code_ = certificate_error_code; 408 certificate_error_code_ = certificate_error_code;
408 409
409 NextProto protocol = default_protocol_; 410 NextProto protocol = default_protocol_;
410 NextProto protocol_negotiated = connection->socket()->GetNegotiatedProtocol(); 411 NextProto protocol_negotiated = connection->socket()->GetNegotiatedProtocol();
411 if (protocol_negotiated != kProtoUnknown) { 412 if (protocol_negotiated != kProtoUnknown) {
412 protocol = protocol_negotiated; 413 protocol = protocol_negotiated;
413 } 414 }
414 415
(...skipping 30 matching lines...) Expand all
445 DCHECK_GT(kDefaultInitialRecvWindowSize, session_recv_window_size_); 446 DCHECK_GT(kDefaultInitialRecvWindowSize, session_recv_window_size_);
446 // This condition implies that |kDefaultInitialRecvWindowSize| - 447 // This condition implies that |kDefaultInitialRecvWindowSize| -
447 // |session_recv_window_size_| doesn't overflow. 448 // |session_recv_window_size_| doesn't overflow.
448 DCHECK_GT(session_recv_window_size_, 0); 449 DCHECK_GT(session_recv_window_size_, 0);
449 IncreaseRecvWindowSize( 450 IncreaseRecvWindowSize(
450 kDefaultInitialRecvWindowSize - session_recv_window_size_); 451 kDefaultInitialRecvWindowSize - session_recv_window_size_);
451 } 452 }
452 453
453 // Write out any data that we might have to send, such as the settings frame. 454 // Write out any data that we might have to send, such as the settings frame.
454 WriteSocketLater(); 455 WriteSocketLater();
455 net::Error error = ReadSocket(); 456 int error = DoLoop(OK);
456 if (error == ERR_IO_PENDING) 457 if (error == ERR_IO_PENDING)
457 return OK; 458 return OK;
458 return error; 459 return static_cast<net::Error>(error);
459 } 460 }
460 461
461 bool SpdySession::VerifyDomainAuthentication(const std::string& domain) { 462 bool SpdySession::VerifyDomainAuthentication(const std::string& domain) {
462 if (!verify_domain_authentication_) 463 if (!verify_domain_authentication_)
463 return true; 464 return true;
464 465
465 if (state_ != CONNECTED) 466 if (!IsConnected())
466 return false; 467 return false;
467 468
468 SSLInfo ssl_info; 469 SSLInfo ssl_info;
469 bool was_npn_negotiated; 470 bool was_npn_negotiated;
470 NextProto protocol_negotiated = kProtoUnknown; 471 NextProto protocol_negotiated = kProtoUnknown;
471 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated)) 472 if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated))
472 return true; // This is not a secure session, so all domains are okay. 473 return true; // This is not a secure session, so all domains are okay.
473 474
474 return !ssl_info.client_cert_sent && 475 return !ssl_info.client_cert_sent &&
475 (enable_credential_frames_ || !ssl_info.channel_id_sent || 476 (enable_credential_frames_ || !ssl_info.channel_id_sent ||
476 ServerBoundCertService::GetDomainForHost(domain) == 477 ServerBoundCertService::GetDomainForHost(domain) ==
477 ServerBoundCertService::GetDomainForHost( 478 ServerBoundCertService::GetDomainForHost(
478 host_port_proxy_pair_.first.host())) && 479 host_port_proxy_pair_.first.host())) &&
479 ssl_info.cert->VerifyNameMatch(domain); 480 ssl_info.cert->VerifyNameMatch(domain);
480 } 481 }
481 482
482 int SpdySession::GetPushStream( 483 int SpdySession::GetPushStream(
483 const GURL& url, 484 const GURL& url,
484 scoped_refptr<SpdyStream>* stream, 485 scoped_refptr<SpdyStream>* stream,
485 const BoundNetLog& stream_net_log) { 486 const BoundNetLog& stream_net_log) {
486 CHECK_NE(state_, CLOSED); 487 CHECK_NE(state_, STATE_CLOSED);
487 488
488 *stream = NULL; 489 *stream = NULL;
489 490
490 // Don't allow access to secure push streams over an unauthenticated, but 491 // Don't allow access to secure push streams over an unauthenticated, but
491 // encrypted SSL socket. 492 // encrypted SSL socket.
492 if (is_secure_ && certificate_error_code_ != OK && 493 if (is_secure_ && certificate_error_code_ != OK &&
493 (url.SchemeIs("https") || url.SchemeIs("wss"))) { 494 (url.SchemeIs("https") || url.SchemeIs("wss"))) {
494 RecordProtocolErrorHistogram( 495 RecordProtocolErrorHistogram(
495 PROTOCOL_ERROR_REQUEST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION); 496 PROTOCOL_ERROR_REQUEST_FOR_SECURE_CONTENT_OVER_INSECURE_SESSION);
496 CloseSessionOnError( 497 CloseSessionOnError(
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 return ContainsKey(active_streams_, stream_id); 860 return ContainsKey(active_streams_, stream_id);
860 } 861 }
861 862
862 LoadState SpdySession::GetLoadState() const { 863 LoadState SpdySession::GetLoadState() const {
863 // NOTE: The application only queries the LoadState via the 864 // NOTE: The application only queries the LoadState via the
864 // SpdyNetworkTransaction, and details are only needed when 865 // SpdyNetworkTransaction, and details are only needed when
865 // we're in the process of connecting. 866 // we're in the process of connecting.
866 867
867 // If we're connecting, defer to the connection to give us the actual 868 // If we're connecting, defer to the connection to give us the actual
868 // LoadState. 869 // LoadState.
869 if (state_ == CONNECTING) 870 if (state_ == STATE_CONNECTING)
870 return connection_->GetLoadState(); 871 return connection_->GetLoadState();
871 872
872 // Just report that we're idle since the session could be doing 873 // Just report that we're idle since the session could be doing
873 // many things concurrently. 874 // many things concurrently.
874 return LOAD_STATE_IDLE; 875 return LOAD_STATE_IDLE;
875 } 876 }
876 877
877 void SpdySession::OnReadComplete(int bytes_read) { 878 void SpdySession::OnReadComplete(int bytes_read) {
878 // Parse a frame. For now this code requires that the frame fit into our 879 DCHECK_NE(state_, STATE_DO_READ);
879 // buffer (32KB). 880 DoLoop(bytes_read);
880 // TODO(mbelshe): support arbitrarily large frames! 881 }
881 882
882 read_pending_ = false; 883 void SpdySession::StartRead() {
884 DCHECK_NE(state_, STATE_DO_READ_COMPLETE);
885 DoLoop(OK);
886 }
883 887
884 if (bytes_read <= 0) { 888 int SpdySession::DoLoop(int result) {
885 // Session is tearing down. 889 bytes_read_ = 0;
886 net::Error error = static_cast<net::Error>(bytes_read);
887 if (bytes_read == 0)
888 error = ERR_CONNECTION_CLOSED;
889 CloseSessionOnError(error, true, "bytes_read is <= 0.");
890 return;
891 }
892
893 bytes_received_ += bytes_read;
894
895 last_activity_time_ = base::TimeTicks::Now();
896 890
897 // The SpdyFramer will use callbacks onto |this| as it parses frames. 891 // The SpdyFramer will use callbacks onto |this| as it parses frames.
898 // When errors occur, those callbacks can lead to teardown of all references 892 // When errors occur, those callbacks can lead to teardown of all references
899 // to |this|, so maintain a reference to self during this call for safe 893 // to |this|, so maintain a reference to self during this call for safe
900 // cleanup. 894 // cleanup.
901 scoped_refptr<SpdySession> self(this); 895 scoped_refptr<SpdySession> self(this);
902 896
897 do {
898 switch (state_) {
899 case STATE_DO_READ:
900 DCHECK_EQ(result, OK);
901 result = DoRead();
902 break;
903 case STATE_DO_READ_COMPLETE:
904 result = DoReadComplete(result);
905 break;
906 case STATE_CLOSED:
907 result = ERR_CONNECTION_CLOSED;
908 break;
909 default:
910 NOTREACHED() << "state_: " << state_;
911 break;
912 }
913 } while (result != ERR_IO_PENDING && state_ != STATE_CLOSED);
914 DCHECK(result == ERR_IO_PENDING || result == ERR_CONNECTION_CLOSED);
915
916 return result;
917 }
918
919 int SpdySession::DoRead() {
920 if (bytes_read_ > kMaxReadBytes) {
921 state_ = STATE_DO_READ;
922 MessageLoop::current()->PostTask(
923 FROM_HERE,
924 base::Bind(&SpdySession::StartRead,
925 weak_factory_.GetWeakPtr()));
926 return ERR_IO_PENDING;
927 }
928
929 CHECK(connection_.get());
930 CHECK(connection_->socket());
931 state_ = STATE_DO_READ_COMPLETE;
932 return connection_->socket()->Read(
933 read_buffer_.get(),
934 kReadBufferSize,
935 base::Bind(&SpdySession::OnReadComplete, weak_factory_.GetWeakPtr()));
936 }
937
938 int SpdySession::DoReadComplete(int result) {
939 // Parse a frame. For now this code requires that the frame fit into our
940 // buffer (32KB).
941 // TODO(mbelshe): support arbitrarily large frames!
942
943 if (result <= 0) {
944 // Session is tearing down.
945 net::Error error = static_cast<net::Error>(result);
946 if (result == 0) {
947 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.EOF",
948 total_bytes_received_, 1, 100000000, 50);
949 error = ERR_CONNECTION_CLOSED;
950 }
951 CloseSessionOnError(error, true, "result is <= 0.");
952 return ERR_CONNECTION_CLOSED;
953 }
954
955 total_bytes_received_ += result;
956 bytes_read_ += result;
957
958 last_activity_time_ = base::TimeTicks::Now();
959
903 DCHECK(buffered_spdy_framer_.get()); 960 DCHECK(buffered_spdy_framer_.get());
904 char* data = read_buffer_->data(); 961 char* data = read_buffer_->data();
905 while (bytes_read && 962 while (result &&
906 buffered_spdy_framer_->error_code() == 963 buffered_spdy_framer_->error_code() ==
907 SpdyFramer::SPDY_NO_ERROR) { 964 SpdyFramer::SPDY_NO_ERROR) {
908 uint32 bytes_processed = 965 uint32 bytes_processed =
909 buffered_spdy_framer_->ProcessInput(data, bytes_read); 966 buffered_spdy_framer_->ProcessInput(data, result);
910 bytes_read -= bytes_processed; 967 result -= bytes_processed;
911 data += bytes_processed; 968 data += bytes_processed;
912 } 969 }
913 970
914 if (state_ != CLOSED) 971 if (!IsConnected())
915 ReadSocket(); 972 return ERR_CONNECTION_CLOSED;
973
974 state_ = STATE_DO_READ;
975 return OK;
916 } 976 }
917 977
918 void SpdySession::OnWriteComplete(int result) { 978 void SpdySession::OnWriteComplete(int result) {
919 // Releasing the in-flight write can have a side-effect of dropping 979 // Releasing the in-flight write can have a side-effect of dropping
920 // the last reference to |this|. Hold a reference through this 980 // the last reference to |this|. Hold a reference through this
921 // function. 981 // function.
922 scoped_refptr<SpdySession> self(this); 982 scoped_refptr<SpdySession> self(this);
923 983
924 DCHECK(write_pending_); 984 DCHECK(write_pending_);
925 DCHECK_GT(in_flight_write_.buffer()->BytesRemaining(), 0); 985 DCHECK_GT(in_flight_write_.buffer()->BytesRemaining(), 0);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 in_flight_write_.Release(); 1019 in_flight_write_.Release();
960 in_flight_write_frame_type_ = DATA; 1020 in_flight_write_frame_type_ = DATA;
961 } 1021 }
962 1022
963 // Write more data. We're already in a continuation, so we can go 1023 // Write more data. We're already in a continuation, so we can go
964 // ahead and write it immediately (without going back to the message 1024 // ahead and write it immediately (without going back to the message
965 // loop). 1025 // loop).
966 WriteSocketLater(); 1026 WriteSocketLater();
967 } 1027 }
968 1028
969 net::Error SpdySession::ReadSocket() {
970 if (read_pending_)
971 return OK;
972
973 if (state_ == CLOSED) {
974 NOTREACHED();
975 return ERR_UNEXPECTED;
976 }
977
978 CHECK(connection_.get());
979 CHECK(connection_->socket());
980 int bytes_read = connection_->socket()->Read(
981 read_buffer_.get(),
982 kReadBufferSize,
983 base::Bind(&SpdySession::OnReadComplete, weak_factory_.GetWeakPtr()));
984 switch (bytes_read) {
985 case 0:
986 // Socket is closed!
987 CloseSessionOnError(ERR_CONNECTION_CLOSED, true, "bytes_read is 0.");
988 return ERR_CONNECTION_CLOSED;
989 case net::ERR_IO_PENDING:
990 // Waiting for data. Nothing to do now.
991 read_pending_ = true;
992 return ERR_IO_PENDING;
993 default:
994 // Data was read, process it.
995 // Schedule the work through the message loop to avoid recursive
996 // callbacks.
997 read_pending_ = true;
998 MessageLoop::current()->PostTask(
999 FROM_HERE,
1000 base::Bind(&SpdySession::OnReadComplete,
1001 weak_factory_.GetWeakPtr(), bytes_read));
1002 break;
1003 }
1004 return OK;
1005 }
1006
1007 void SpdySession::WriteSocketLater() { 1029 void SpdySession::WriteSocketLater() {
1008 if (delayed_write_pending_) 1030 if (delayed_write_pending_)
1009 return; 1031 return;
1010 1032
1011 if (state_ < CONNECTED) 1033 if (!IsConnected())
1012 return; 1034 return;
1013 1035
1014 delayed_write_pending_ = true; 1036 delayed_write_pending_ = true;
1015 MessageLoop::current()->PostTask( 1037 MessageLoop::current()->PostTask(
1016 FROM_HERE, 1038 FROM_HERE,
1017 base::Bind(&SpdySession::WriteSocket, weak_factory_.GetWeakPtr())); 1039 base::Bind(&SpdySession::WriteSocket, weak_factory_.GetWeakPtr()));
1018 } 1040 }
1019 1041
1020 void SpdySession::WriteSocket() { 1042 void SpdySession::WriteSocket() {
1021 // This function should only be called via WriteSocketLater. 1043 // This function should only be called via WriteSocketLater.
1022 DCHECK(delayed_write_pending_); 1044 DCHECK(delayed_write_pending_);
1023 delayed_write_pending_ = false; 1045 delayed_write_pending_ = false;
1024 1046
1025 // If the socket isn't connected yet, just wait; we'll get called 1047 // If the socket isn't connected yet, just wait; we'll get called
1026 // again when the socket connection completes. If the socket is 1048 // again when the socket connection completes. If the socket is
1027 // closed, just return. 1049 // closed, just return.
1028 if (state_ < CONNECTED || state_ == CLOSED) 1050 if (!IsConnected())
1029 return; 1051 return;
1030 1052
1031 if (write_pending_) // Another write is in progress still. 1053 if (write_pending_) // Another write is in progress still.
1032 return; 1054 return;
1033 1055
1034 // Loop sending frames until we've sent everything or until the write 1056 // Loop sending frames until we've sent everything or until the write
1035 // returns error (or ERR_IO_PENDING). 1057 // returns error (or ERR_IO_PENDING).
1036 DCHECK(buffered_spdy_framer_.get()); 1058 DCHECK(buffered_spdy_framer_.get());
1037 while (true) { 1059 while (true) {
1038 if (in_flight_write_.buffer()) { 1060 if (in_flight_write_.buffer()) {
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 scoped_refptr<SpdySession> self(this); 1183 scoped_refptr<SpdySession> self(this);
1162 1184
1163 DCHECK_LT(err, OK); 1185 DCHECK_LT(err, OK);
1164 net_log_.AddEvent( 1186 net_log_.AddEvent(
1165 NetLog::TYPE_SPDY_SESSION_CLOSE, 1187 NetLog::TYPE_SPDY_SESSION_CLOSE,
1166 base::Bind(&NetLogSpdySessionCloseCallback, err, &description)); 1188 base::Bind(&NetLogSpdySessionCloseCallback, err, &description));
1167 1189
1168 // Don't close twice. This can occur because we can have both 1190 // Don't close twice. This can occur because we can have both
1169 // a read and a write outstanding, and each can complete with 1191 // a read and a write outstanding, and each can complete with
1170 // an error. 1192 // an error.
1171 if (state_ != CLOSED) { 1193 if (!IsClosed()) {
1172 state_ = CLOSED; 1194 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SpdySession.ClosedOnError", -err);
1195 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySession.BytesRead.OtherErrors",
1196 total_bytes_received_, 1, 100000000, 50);
1197 state_ = STATE_CLOSED;
1173 error_ = err; 1198 error_ = err;
1174 if (remove_from_pool) 1199 if (remove_from_pool)
1175 RemoveFromPool(); 1200 RemoveFromPool();
1176 CloseAllStreams(err); 1201 CloseAllStreams(err);
1177 } 1202 }
1178 } 1203 }
1179 1204
1180 base::Value* SpdySession::GetInfoAsValue() const { 1205 base::Value* SpdySession::GetInfoAsValue() const {
1181 base::DictionaryValue* dict = new base::DictionaryValue(); 1206 base::DictionaryValue* dict = new base::DictionaryValue();
1182 1207
(...skipping 914 matching lines...) Expand 10 before | Expand all | Expand 10 after
2097 SettingsMap::const_iterator it; 2122 SettingsMap::const_iterator it;
2098 for (it = settings_map.begin(); it != settings_map.end(); ++it) { 2123 for (it = settings_map.begin(); it != settings_map.end(); ++it) {
2099 const SpdySettingsIds id = it->first; 2124 const SpdySettingsIds id = it->first;
2100 const uint32 val = it->second.second; 2125 const uint32 val = it->second.second;
2101 switch (id) { 2126 switch (id) {
2102 case SETTINGS_CURRENT_CWND: 2127 case SETTINGS_CURRENT_CWND:
2103 // Record several different histograms to see if cwnd converges 2128 // Record several different histograms to see if cwnd converges
2104 // for larger volumes of data being sent. 2129 // for larger volumes of data being sent.
2105 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd", 2130 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd",
2106 val, 1, 200, 100); 2131 val, 1, 200, 100);
2107 if (bytes_received_ > 10 * 1024) { 2132 if (total_bytes_received_ > 10 * 1024) {
2108 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd10K", 2133 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd10K",
2109 val, 1, 200, 100); 2134 val, 1, 200, 100);
2110 if (bytes_received_ > 25 * 1024) { 2135 if (total_bytes_received_ > 25 * 1024) {
2111 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd25K", 2136 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd25K",
2112 val, 1, 200, 100); 2137 val, 1, 200, 100);
2113 if (bytes_received_ > 50 * 1024) { 2138 if (total_bytes_received_ > 50 * 1024) {
2114 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd50K", 2139 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd50K",
2115 val, 1, 200, 100); 2140 val, 1, 200, 100);
2116 if (bytes_received_ > 100 * 1024) { 2141 if (total_bytes_received_ > 100 * 1024) {
2117 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd100K", 2142 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsCwnd100K",
2118 val, 1, 200, 100); 2143 val, 1, 200, 100);
2119 } 2144 }
2120 } 2145 }
2121 } 2146 }
2122 } 2147 }
2123 break; 2148 break;
2124 case SETTINGS_ROUND_TRIP_TIME: 2149 case SETTINGS_ROUND_TRIP_TIME:
2125 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRTT", 2150 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SpdySettingsRTT",
2126 val, 1, 1200, 100); 2151 val, 1, 1200, 100);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
2285 } 2310 }
2286 2311
2287 session_recv_window_size_ -= delta_window_size; 2312 session_recv_window_size_ -= delta_window_size;
2288 net_log_.AddEvent( 2313 net_log_.AddEvent(
2289 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW, 2314 NetLog::TYPE_SPDY_SESSION_UPDATE_RECV_WINDOW,
2290 base::Bind(&NetLogSpdySessionWindowUpdateCallback, 2315 base::Bind(&NetLogSpdySessionWindowUpdateCallback,
2291 -delta_window_size, session_recv_window_size_)); 2316 -delta_window_size, session_recv_window_size_));
2292 } 2317 }
2293 2318
2294 } // namespace net 2319 } // 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