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/socket/client_socket_pool_base.h" | 5 #include "net/socket/client_socket_pool_base.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
118 LogConnectCompletion(rv); | 118 LogConnectCompletion(rv); |
119 delegate->OnConnectJobComplete(rv, this); | 119 delegate->OnConnectJobComplete(rv, this); |
120 } | 120 } |
121 | 121 |
122 void ConnectJob::ResetTimer(base::TimeDelta remaining_time) { | 122 void ConnectJob::ResetTimer(base::TimeDelta remaining_time) { |
123 timer_.Stop(); | 123 timer_.Stop(); |
124 timer_.Start(FROM_HERE, remaining_time, this, &ConnectJob::OnTimeout); | 124 timer_.Start(FROM_HERE, remaining_time, this, &ConnectJob::OnTimeout); |
125 } | 125 } |
126 | 126 |
127 void ConnectJob::LogConnectStart() { | 127 void ConnectJob::LogConnectStart() { |
128 connect_timing().connect_start = base::TimeTicks::Now(); | |
128 net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT, | 129 net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT, |
129 NetLog::StringCallback("group_name", &group_name_)); | 130 NetLog::StringCallback("group_name", &group_name_)); |
130 } | 131 } |
131 | 132 |
132 void ConnectJob::LogConnectCompletion(int net_error) { | 133 void ConnectJob::LogConnectCompletion(int net_error) { |
134 connect_timing().connect_end = base::TimeTicks::Now(); | |
133 net_log().EndEventWithNetErrorCode( | 135 net_log().EndEventWithNetErrorCode( |
134 NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT, net_error); | 136 NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT, net_error); |
135 } | 137 } |
136 | 138 |
137 void ConnectJob::OnTimeout() { | 139 void ConnectJob::OnTimeout() { |
138 // Make sure the socket is NULL before calling into |delegate|. | 140 // Make sure the socket is NULL before calling into |delegate|. |
139 set_socket(NULL); | 141 set_socket(NULL); |
140 | 142 |
141 net_log_.AddEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT); | 143 net_log_.AddEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT); |
142 | 144 |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
376 // We couldn't find a socket to reuse, and there's space to allocate one, | 378 // We couldn't find a socket to reuse, and there's space to allocate one, |
377 // so allocate and connect a new one. | 379 // so allocate and connect a new one. |
378 scoped_ptr<ConnectJob> connect_job( | 380 scoped_ptr<ConnectJob> connect_job( |
379 connect_job_factory_->NewConnectJob(group_name, *request, this)); | 381 connect_job_factory_->NewConnectJob(group_name, *request, this)); |
380 | 382 |
381 int rv = connect_job->Connect(); | 383 int rv = connect_job->Connect(); |
382 if (rv == OK) { | 384 if (rv == OK) { |
383 LogBoundConnectJobToRequest(connect_job->net_log().source(), request); | 385 LogBoundConnectJobToRequest(connect_job->net_log().source(), request); |
384 if (!preconnecting) { | 386 if (!preconnecting) { |
385 HandOutSocket(connect_job->ReleaseSocket(), false /* not reused */, | 387 HandOutSocket(connect_job->ReleaseSocket(), false /* not reused */, |
386 handle, base::TimeDelta(), group, request->net_log()); | 388 connect_job->connect_timing(), handle, base::TimeDelta(), |
389 group, request->net_log()); | |
387 } else { | 390 } else { |
388 AddIdleSocket(connect_job->ReleaseSocket(), group); | 391 AddIdleSocket(connect_job->ReleaseSocket(), group); |
389 } | 392 } |
390 } else if (rv == ERR_IO_PENDING) { | 393 } else if (rv == ERR_IO_PENDING) { |
391 // If we don't have any sockets in this group, set a timer for potentially | 394 // If we don't have any sockets in this group, set a timer for potentially |
392 // creating a new one. If the SYN is lost, this backup socket may complete | 395 // creating a new one. If the SYN is lost, this backup socket may complete |
393 // before the slow socket, improving end user latency. | 396 // before the slow socket, improving end user latency. |
394 if (connect_backup_jobs_enabled_ && | 397 if (connect_backup_jobs_enabled_ && |
395 group->IsEmpty() && !group->HasBackupJob()) { | 398 group->IsEmpty() && !group->HasBackupJob()) { |
396 group->StartBackupSocketTimer(group_name, this); | 399 group->StartBackupSocketTimer(group_name, this); |
397 } | 400 } |
398 | 401 |
399 connecting_socket_count_++; | 402 connecting_socket_count_++; |
400 | 403 |
401 group->AddJob(connect_job.release(), preconnecting); | 404 group->AddJob(connect_job.release(), preconnecting); |
402 } else { | 405 } else { |
403 LogBoundConnectJobToRequest(connect_job->net_log().source(), request); | 406 LogBoundConnectJobToRequest(connect_job->net_log().source(), request); |
404 StreamSocket* error_socket = NULL; | 407 StreamSocket* error_socket = NULL; |
405 if (!preconnecting) { | 408 if (!preconnecting) { |
406 DCHECK(handle); | 409 DCHECK(handle); |
407 connect_job->GetAdditionalErrorState(handle); | 410 connect_job->GetAdditionalErrorState(handle); |
408 error_socket = connect_job->ReleaseSocket(); | 411 error_socket = connect_job->ReleaseSocket(); |
409 } | 412 } |
410 if (error_socket) { | 413 if (error_socket) { |
411 HandOutSocket(error_socket, false /* not reused */, handle, | 414 HandOutSocket(error_socket, false /* not reused */, |
412 base::TimeDelta(), group, request->net_log()); | 415 connect_job->connect_timing(), handle, base::TimeDelta(), |
416 group, request->net_log()); | |
413 } else if (group->IsEmpty()) { | 417 } else if (group->IsEmpty()) { |
414 RemoveGroup(group_name); | 418 RemoveGroup(group_name); |
415 } | 419 } |
416 } | 420 } |
417 | 421 |
418 return rv; | 422 return rv; |
419 } | 423 } |
420 | 424 |
421 bool ClientSocketPoolBaseHelper::AssignIdleSocketToRequest( | 425 bool ClientSocketPoolBaseHelper::AssignIdleSocketToRequest( |
422 const Request* request, Group* group) { | 426 const Request* request, Group* group) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
468 | 472 |
469 if (idle_socket_it != idle_sockets->end()) { | 473 if (idle_socket_it != idle_sockets->end()) { |
470 DecrementIdleCount(); | 474 DecrementIdleCount(); |
471 base::TimeDelta idle_time = | 475 base::TimeDelta idle_time = |
472 base::TimeTicks::Now() - idle_socket_it->start_time; | 476 base::TimeTicks::Now() - idle_socket_it->start_time; |
473 IdleSocket idle_socket = *idle_socket_it; | 477 IdleSocket idle_socket = *idle_socket_it; |
474 idle_sockets->erase(idle_socket_it); | 478 idle_sockets->erase(idle_socket_it); |
475 HandOutSocket( | 479 HandOutSocket( |
476 idle_socket.socket, | 480 idle_socket.socket, |
477 idle_socket.socket->WasEverUsed(), | 481 idle_socket.socket->WasEverUsed(), |
482 ConnectTiming(), | |
478 request->handle(), | 483 request->handle(), |
479 idle_time, | 484 idle_time, |
480 group, | 485 group, |
481 request->net_log()); | 486 request->net_log()); |
482 return true; | 487 return true; |
483 } | 488 } |
484 | 489 |
485 return false; | 490 return false; |
486 } | 491 } |
487 | 492 |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
849 int result, ConnectJob* job) { | 854 int result, ConnectJob* job) { |
850 DCHECK_NE(ERR_IO_PENDING, result); | 855 DCHECK_NE(ERR_IO_PENDING, result); |
851 const std::string group_name = job->group_name(); | 856 const std::string group_name = job->group_name(); |
852 GroupMap::iterator group_it = group_map_.find(group_name); | 857 GroupMap::iterator group_it = group_map_.find(group_name); |
853 CHECK(group_it != group_map_.end()); | 858 CHECK(group_it != group_map_.end()); |
854 Group* group = group_it->second; | 859 Group* group = group_it->second; |
855 | 860 |
856 scoped_ptr<StreamSocket> socket(job->ReleaseSocket()); | 861 scoped_ptr<StreamSocket> socket(job->ReleaseSocket()); |
857 | 862 |
858 BoundNetLog job_log = job->net_log(); | 863 BoundNetLog job_log = job->net_log(); |
864 ConnectTiming connect_timing = job->connect_timing(); | |
eroman
2012/12/14 04:08:35
Could you add a comment above these 2 lines, menti
mmenke
2012/12/14 13:36:12
Done.
| |
859 | 865 |
860 if (result == OK) { | 866 if (result == OK) { |
861 DCHECK(socket.get()); | 867 DCHECK(socket.get()); |
862 RemoveConnectJob(job, group); | 868 RemoveConnectJob(job, group); |
863 if (!group->pending_requests().empty()) { | 869 if (!group->pending_requests().empty()) { |
864 scoped_ptr<const Request> r(RemoveRequestFromQueue( | 870 scoped_ptr<const Request> r(RemoveRequestFromQueue( |
865 group->mutable_pending_requests()->begin(), group)); | 871 group->mutable_pending_requests()->begin(), group)); |
866 LogBoundConnectJobToRequest(job_log.source(), r.get()); | 872 LogBoundConnectJobToRequest(job_log.source(), r.get()); |
867 HandOutSocket( | 873 HandOutSocket( |
868 socket.release(), false /* unused socket */, r->handle(), | 874 socket.release(), false /* unused socket */, connect_timing, |
869 base::TimeDelta(), group, r->net_log()); | 875 r->handle(), base::TimeDelta(), group, r->net_log()); |
870 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); | 876 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); |
871 InvokeUserCallbackLater(r->handle(), r->callback(), result); | 877 InvokeUserCallbackLater(r->handle(), r->callback(), result); |
872 } else { | 878 } else { |
873 AddIdleSocket(socket.release(), group); | 879 AddIdleSocket(socket.release(), group); |
874 OnAvailableSocketSlot(group_name, group); | 880 OnAvailableSocketSlot(group_name, group); |
875 CheckForStalledSocketGroups(); | 881 CheckForStalledSocketGroups(); |
876 } | 882 } |
877 } else { | 883 } else { |
878 // If we got a socket, it must contain error information so pass that | 884 // If we got a socket, it must contain error information so pass that |
879 // up so that the caller can retrieve it. | 885 // up so that the caller can retrieve it. |
880 bool handed_out_socket = false; | 886 bool handed_out_socket = false; |
881 if (!group->pending_requests().empty()) { | 887 if (!group->pending_requests().empty()) { |
882 scoped_ptr<const Request> r(RemoveRequestFromQueue( | 888 scoped_ptr<const Request> r(RemoveRequestFromQueue( |
883 group->mutable_pending_requests()->begin(), group)); | 889 group->mutable_pending_requests()->begin(), group)); |
884 LogBoundConnectJobToRequest(job_log.source(), r.get()); | 890 LogBoundConnectJobToRequest(job_log.source(), r.get()); |
885 job->GetAdditionalErrorState(r->handle()); | 891 job->GetAdditionalErrorState(r->handle()); |
886 RemoveConnectJob(job, group); | 892 RemoveConnectJob(job, group); |
887 if (socket.get()) { | 893 if (socket.get()) { |
888 handed_out_socket = true; | 894 handed_out_socket = true; |
889 HandOutSocket(socket.release(), false /* unused socket */, r->handle(), | 895 HandOutSocket(socket.release(), false /* unused socket */, |
890 base::TimeDelta(), group, r->net_log()); | 896 connect_timing, r->handle(), base::TimeDelta(), group, |
897 r->net_log()); | |
891 } | 898 } |
892 r->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, | 899 r->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, result); |
893 result); | |
894 InvokeUserCallbackLater(r->handle(), r->callback(), result); | 900 InvokeUserCallbackLater(r->handle(), r->callback(), result); |
895 } else { | 901 } else { |
896 RemoveConnectJob(job, group); | 902 RemoveConnectJob(job, group); |
897 } | 903 } |
898 if (!handed_out_socket) { | 904 if (!handed_out_socket) { |
899 OnAvailableSocketSlot(group_name, group); | 905 OnAvailableSocketSlot(group_name, group); |
900 CheckForStalledSocketGroups(); | 906 CheckForStalledSocketGroups(); |
901 } | 907 } |
902 } | 908 } |
903 } | 909 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
970 RemoveGroup(group_name); | 976 RemoveGroup(group_name); |
971 | 977 |
972 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); | 978 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); |
973 InvokeUserCallbackLater(request->handle(), request->callback(), rv); | 979 InvokeUserCallbackLater(request->handle(), request->callback(), rv); |
974 } | 980 } |
975 } | 981 } |
976 | 982 |
977 void ClientSocketPoolBaseHelper::HandOutSocket( | 983 void ClientSocketPoolBaseHelper::HandOutSocket( |
978 StreamSocket* socket, | 984 StreamSocket* socket, |
979 bool reused, | 985 bool reused, |
986 const ConnectTiming& connect_timing, | |
980 ClientSocketHandle* handle, | 987 ClientSocketHandle* handle, |
981 base::TimeDelta idle_time, | 988 base::TimeDelta idle_time, |
982 Group* group, | 989 Group* group, |
983 const BoundNetLog& net_log) { | 990 const BoundNetLog& net_log) { |
984 DCHECK(socket); | 991 DCHECK(socket); |
985 handle->set_socket(socket); | 992 handle->set_socket(socket); |
986 handle->set_is_reused(reused); | 993 handle->set_is_reused(reused); |
987 handle->set_idle_time(idle_time); | 994 handle->set_idle_time(idle_time); |
988 handle->set_pool_id(pool_generation_number_); | 995 handle->set_pool_id(pool_generation_number_); |
996 handle->set_connect_timing(connect_timing); | |
989 | 997 |
990 if (reused) { | 998 if (reused) { |
991 net_log.AddEvent( | 999 net_log.AddEvent( |
992 NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET, | 1000 NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET, |
993 NetLog::IntegerCallback( | 1001 NetLog::IntegerCallback( |
994 "idle_ms", static_cast<int>(idle_time.InMilliseconds()))); | 1002 "idle_ms", static_cast<int>(idle_time.InMilliseconds()))); |
995 } | 1003 } |
996 | 1004 |
997 net_log.AddEvent(NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET, | 1005 net_log.AddEvent(NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET, |
998 socket->NetLog().source().ToEventParametersCallback()); | 1006 socket->NetLog().source().ToEventParametersCallback()); |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1229 STLDeleteElements(&jobs_); | 1237 STLDeleteElements(&jobs_); |
1230 unassigned_job_count_ = 0; | 1238 unassigned_job_count_ = 0; |
1231 | 1239 |
1232 // Cancel pending backup job. | 1240 // Cancel pending backup job. |
1233 weak_factory_.InvalidateWeakPtrs(); | 1241 weak_factory_.InvalidateWeakPtrs(); |
1234 } | 1242 } |
1235 | 1243 |
1236 } // namespace internal | 1244 } // namespace internal |
1237 | 1245 |
1238 } // namespace net | 1246 } // namespace net |
OLD | NEW |