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/socket/client_socket_pool_base.h" | 5 #include "net/socket/client_socket_pool_base.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/format_macros.h" | 8 #include "base/format_macros.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/stats_counters.h" | 10 #include "base/stats_counters.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 | 31 |
32 namespace net { | 32 namespace net { |
33 | 33 |
34 ConnectJob::ConnectJob(const std::string& group_name, | 34 ConnectJob::ConnectJob(const std::string& group_name, |
35 base::TimeDelta timeout_duration, | 35 base::TimeDelta timeout_duration, |
36 Delegate* delegate, | 36 Delegate* delegate, |
37 const BoundNetLog& net_log) | 37 const BoundNetLog& net_log) |
38 : group_name_(group_name), | 38 : group_name_(group_name), |
39 timeout_duration_(timeout_duration), | 39 timeout_duration_(timeout_duration), |
40 delegate_(delegate), | 40 delegate_(delegate), |
41 net_log_(net_log) { | 41 net_log_(net_log), |
| 42 idle_(true) { |
42 DCHECK(!group_name.empty()); | 43 DCHECK(!group_name.empty()); |
43 DCHECK(delegate); | 44 DCHECK(delegate); |
44 } | 45 } |
45 | 46 |
46 ConnectJob::~ConnectJob() { | 47 ConnectJob::~ConnectJob() { |
47 if (delegate_) { | 48 if (delegate_ && !idle_) { |
48 // If the delegate was not NULLed, then NotifyDelegateOfCompletion has | 49 // If the delegate was not NULLed, then NotifyDelegateOfCompletion has |
49 // not been called yet (hence we are cancelling). | 50 // not been called yet. If we've started then we are cancelling. |
50 net_log_.AddEvent(NetLog::TYPE_CANCELLED); | 51 net_log_.AddEvent(NetLog::TYPE_CANCELLED); |
51 net_log_.EndEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB); | 52 net_log_.EndEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB); |
52 } | 53 } |
53 } | 54 } |
54 | 55 |
55 int ConnectJob::Connect() { | 56 int ConnectJob::Connect() { |
56 if (timeout_duration_ != base::TimeDelta()) | 57 if (timeout_duration_ != base::TimeDelta()) |
57 timer_.Start(timeout_duration_, this, &ConnectJob::OnTimeout); | 58 timer_.Start(timeout_duration_, this, &ConnectJob::OnTimeout); |
58 | 59 |
59 net_log_.BeginEventWithString(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB, | 60 net_log_.BeginEventWithString(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB, |
60 group_name_); | 61 group_name_); |
| 62 idle_ = false; |
61 | 63 |
62 int rv = ConnectInternal(); | 64 int rv = ConnectInternal(); |
63 | 65 |
64 if (rv != ERR_IO_PENDING) { | 66 if (rv != ERR_IO_PENDING) { |
65 delegate_ = NULL; | 67 delegate_ = NULL; |
66 net_log_.EndEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB); | 68 net_log_.EndEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB); |
67 } | 69 } |
68 | 70 |
69 return rv; | 71 return rv; |
70 } | 72 } |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 | 226 |
225 // See if we already have enough connect jobs or sockets that will be released | 227 // See if we already have enough connect jobs or sockets that will be released |
226 // soon. | 228 // soon. |
227 if (group.HasReleasingSockets()) { | 229 if (group.HasReleasingSockets()) { |
228 return ERR_IO_PENDING; | 230 return ERR_IO_PENDING; |
229 } | 231 } |
230 | 232 |
231 // We couldn't find a socket to reuse, so allocate and connect a new one. | 233 // We couldn't find a socket to reuse, so allocate and connect a new one. |
232 BoundNetLog job_net_log = BoundNetLog::Make( | 234 BoundNetLog job_net_log = BoundNetLog::Make( |
233 request->net_log().net_log(), NetLog::SOURCE_CONNECT_JOB); | 235 request->net_log().net_log(), NetLog::SOURCE_CONNECT_JOB); |
| 236 request->net_log().BeginEventWithInteger( |
| 237 NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID, job_net_log.source().id); |
234 | 238 |
235 scoped_ptr<ConnectJob> connect_job( | 239 scoped_ptr<ConnectJob> connect_job( |
236 connect_job_factory_->NewConnectJob(group_name, *request, this, | 240 connect_job_factory_->NewConnectJob(group_name, *request, this, |
237 job_net_log)); | 241 job_net_log)); |
238 | 242 |
239 int rv = connect_job->Connect(); | 243 int rv = connect_job->Connect(); |
240 | |
241 if (rv != ERR_IO_PENDING) { | |
242 request->net_log().AddEventWithInteger( | |
243 NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID, | |
244 job_net_log.source().id); | |
245 } | |
246 | |
247 if (rv == OK) { | 244 if (rv == OK) { |
| 245 request->net_log().EndEventWithInteger( |
| 246 NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID, job_net_log.source().id); |
248 HandOutSocket(connect_job->ReleaseSocket(), false /* not reused */, | 247 HandOutSocket(connect_job->ReleaseSocket(), false /* not reused */, |
249 handle, base::TimeDelta(), &group, request->net_log()); | 248 handle, base::TimeDelta(), &group, request->net_log()); |
250 } else if (rv == ERR_IO_PENDING) { | 249 } else if (rv == ERR_IO_PENDING) { |
251 // If we don't have any sockets in this group, set a timer for potentially | 250 // If we don't have any sockets in this group, set a timer for potentially |
252 // creating a new one. If the SYN is lost, this backup socket may complete | 251 // creating a new one. If the SYN is lost, this backup socket may complete |
253 // before the slow socket, improving end user latency. | 252 // before the slow socket, improving end user latency. |
254 if (group.IsEmpty() && !group.backup_job && backup_jobs_enabled_) { | 253 if (group.IsEmpty() && !group.backup_job && backup_jobs_enabled_) { |
255 group.backup_job = connect_job_factory_->NewConnectJob(group_name, | 254 group.backup_job = connect_job_factory_->NewConnectJob(group_name, |
256 *request, | 255 *request, |
257 this, | 256 this, |
258 job_net_log); | 257 job_net_log); |
259 StartBackupSocketTimer(group_name); | 258 StartBackupSocketTimer(group_name); |
260 } | 259 } |
261 | 260 |
262 connecting_socket_count_++; | 261 connecting_socket_count_++; |
263 | 262 |
264 ConnectJob* job = connect_job.release(); | 263 ConnectJob* job = connect_job.release(); |
265 group.jobs.insert(job); | 264 group.jobs.insert(job); |
266 } else if (group.IsEmpty()) { | 265 } else { |
267 group_map_.erase(group_name); | 266 request->net_log().EndEventWithInteger( |
| 267 NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID, job_net_log.source().id); |
| 268 if (group.IsEmpty()) |
| 269 group_map_.erase(group_name); |
268 } | 270 } |
269 | 271 |
270 return rv; | 272 return rv; |
271 } | 273 } |
272 | 274 |
273 void ClientSocketPoolBaseHelper::StartBackupSocketTimer( | 275 void ClientSocketPoolBaseHelper::StartBackupSocketTimer( |
274 const std::string& group_name) { | 276 const std::string& group_name) { |
275 CHECK(ContainsKey(group_map_, group_name)); | 277 CHECK(ContainsKey(group_map_, group_name)); |
276 Group& group = group_map_[group_name]; | 278 Group& group = group_map_[group_name]; |
277 | 279 |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 scoped_ptr<ClientSocket> socket(job->ReleaseSocket()); | 561 scoped_ptr<ClientSocket> socket(job->ReleaseSocket()); |
560 | 562 |
561 BoundNetLog job_log = job->net_log(); | 563 BoundNetLog job_log = job->net_log(); |
562 RemoveConnectJob(job, &group); | 564 RemoveConnectJob(job, &group); |
563 | 565 |
564 if (result == OK) { | 566 if (result == OK) { |
565 DCHECK(socket.get()); | 567 DCHECK(socket.get()); |
566 if (!group.pending_requests.empty()) { | 568 if (!group.pending_requests.empty()) { |
567 scoped_ptr<const Request> r(RemoveRequestFromQueue( | 569 scoped_ptr<const Request> r(RemoveRequestFromQueue( |
568 group.pending_requests.begin(), &group.pending_requests)); | 570 group.pending_requests.begin(), &group.pending_requests)); |
569 r->net_log().AddEventWithInteger(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID, | 571 r->net_log().EndEventWithInteger(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID, |
570 job_log.source().id); | 572 job_log.source().id); |
571 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); | 573 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); |
572 HandOutSocket( | 574 HandOutSocket( |
573 socket.release(), false /* unused socket */, r->handle(), | 575 socket.release(), false /* unused socket */, r->handle(), |
574 base::TimeDelta(), &group, r->net_log()); | 576 base::TimeDelta(), &group, r->net_log()); |
575 r->callback()->Run(result); | 577 r->callback()->Run(result); |
576 } else { | 578 } else { |
577 AddIdleSocket(socket.release(), false /* unused socket */, &group); | 579 AddIdleSocket(socket.release(), false /* unused socket */, &group); |
578 OnAvailableSocketSlot(group_name, &group); | 580 OnAvailableSocketSlot(group_name, &group); |
579 } | 581 } |
580 } else { | 582 } else { |
581 DCHECK(!socket.get()); | 583 DCHECK(!socket.get()); |
582 if (!group.pending_requests.empty()) { | 584 if (!group.pending_requests.empty()) { |
583 scoped_ptr<const Request> r(RemoveRequestFromQueue( | 585 scoped_ptr<const Request> r(RemoveRequestFromQueue( |
584 group.pending_requests.begin(), &group.pending_requests)); | 586 group.pending_requests.begin(), &group.pending_requests)); |
585 r->net_log().AddEventWithInteger(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID, | 587 r->net_log().EndEventWithInteger(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_ID, |
586 job_log.source().id); | 588 job_log.source().id); |
587 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); | 589 r->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); |
588 r->callback()->Run(result); | 590 r->callback()->Run(result); |
589 } | 591 } |
590 MaybeOnAvailableSocketSlot(group_name); | 592 MaybeOnAvailableSocketSlot(group_name); |
591 } | 593 } |
592 } | 594 } |
593 | 595 |
594 void ClientSocketPoolBaseHelper::OnIPAddressChanged() { | 596 void ClientSocketPoolBaseHelper::OnIPAddressChanged() { |
595 CloseIdleSockets(); | 597 CloseIdleSockets(); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
671 handle->set_is_reused(reused); | 673 handle->set_is_reused(reused); |
672 handle->set_idle_time(idle_time); | 674 handle->set_idle_time(idle_time); |
673 | 675 |
674 if (reused) | 676 if (reused) |
675 net_log.AddStringLiteral("Reusing socket."); | 677 net_log.AddStringLiteral("Reusing socket."); |
676 if (idle_time != base::TimeDelta()) { | 678 if (idle_time != base::TimeDelta()) { |
677 net_log.AddString( | 679 net_log.AddString( |
678 StringPrintf("Socket sat idle for %" PRId64 " milliseconds", | 680 StringPrintf("Socket sat idle for %" PRId64 " milliseconds", |
679 idle_time.InMilliseconds())); | 681 idle_time.InMilliseconds())); |
680 } | 682 } |
| 683 net_log.AddEventWithInteger(NetLog::TYPE_SOCKET_POOL_SOCKET_ID, |
| 684 socket->NetLog().source().id); |
681 | 685 |
682 handed_out_socket_count_++; | 686 handed_out_socket_count_++; |
683 group->active_socket_count++; | 687 group->active_socket_count++; |
684 } | 688 } |
685 | 689 |
686 void ClientSocketPoolBaseHelper::AddIdleSocket( | 690 void ClientSocketPoolBaseHelper::AddIdleSocket( |
687 ClientSocket* socket, bool used, Group* group) { | 691 ClientSocket* socket, bool used, Group* group) { |
688 DCHECK(socket); | 692 DCHECK(socket); |
689 IdleSocket idle_socket; | 693 IdleSocket idle_socket; |
690 idle_socket.socket = socket; | 694 idle_socket.socket = socket; |
(...skipping 27 matching lines...) Expand all Loading... |
718 bool ClientSocketPoolBaseHelper::ReachedMaxSocketsLimit() const { | 722 bool ClientSocketPoolBaseHelper::ReachedMaxSocketsLimit() const { |
719 // Each connecting socket will eventually connect and be handed out. | 723 // Each connecting socket will eventually connect and be handed out. |
720 int total = handed_out_socket_count_ + connecting_socket_count_; | 724 int total = handed_out_socket_count_ + connecting_socket_count_; |
721 DCHECK_LE(total, max_sockets_); | 725 DCHECK_LE(total, max_sockets_); |
722 return total == max_sockets_; | 726 return total == max_sockets_; |
723 } | 727 } |
724 | 728 |
725 } // namespace internal | 729 } // namespace internal |
726 | 730 |
727 } // namespace net | 731 } // namespace net |
OLD | NEW |