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 <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 DCHECK(!group_name.empty()); | 67 DCHECK(!group_name.empty()); |
68 DCHECK(delegate); | 68 DCHECK(delegate); |
69 net_log.BeginEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB, | 69 net_log.BeginEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB, |
70 NetLog::StringCallback("group_name", &group_name_)); | 70 NetLog::StringCallback("group_name", &group_name_)); |
71 } | 71 } |
72 | 72 |
73 ConnectJob::~ConnectJob() { | 73 ConnectJob::~ConnectJob() { |
74 net_log().EndEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB); | 74 net_log().EndEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB); |
75 } | 75 } |
76 | 76 |
77 scoped_ptr<StreamSocket> ConnectJob::PassSocket() { | 77 std::unique_ptr<StreamSocket> ConnectJob::PassSocket() { |
78 return std::move(socket_); | 78 return std::move(socket_); |
79 } | 79 } |
80 | 80 |
81 int ConnectJob::Connect() { | 81 int ConnectJob::Connect() { |
82 if (timeout_duration_ != base::TimeDelta()) | 82 if (timeout_duration_ != base::TimeDelta()) |
83 timer_.Start(FROM_HERE, timeout_duration_, this, &ConnectJob::OnTimeout); | 83 timer_.Start(FROM_HERE, timeout_duration_, this, &ConnectJob::OnTimeout); |
84 | 84 |
85 idle_ = false; | 85 idle_ = false; |
86 | 86 |
87 LogConnectStart(); | 87 LogConnectStart(); |
88 | 88 |
89 int rv = ConnectInternal(); | 89 int rv = ConnectInternal(); |
90 | 90 |
91 if (rv != ERR_IO_PENDING) { | 91 if (rv != ERR_IO_PENDING) { |
92 LogConnectCompletion(rv); | 92 LogConnectCompletion(rv); |
93 delegate_ = NULL; | 93 delegate_ = NULL; |
94 } | 94 } |
95 | 95 |
96 return rv; | 96 return rv; |
97 } | 97 } |
98 | 98 |
99 void ConnectJob::SetSocket(scoped_ptr<StreamSocket> socket) { | 99 void ConnectJob::SetSocket(std::unique_ptr<StreamSocket> socket) { |
100 if (socket) { | 100 if (socket) { |
101 net_log().AddEvent(NetLog::TYPE_CONNECT_JOB_SET_SOCKET, | 101 net_log().AddEvent(NetLog::TYPE_CONNECT_JOB_SET_SOCKET, |
102 socket->NetLog().source().ToEventParametersCallback()); | 102 socket->NetLog().source().ToEventParametersCallback()); |
103 } | 103 } |
104 socket_ = std::move(socket); | 104 socket_ = std::move(socket); |
105 } | 105 } |
106 | 106 |
107 void ConnectJob::NotifyDelegateOfCompletion(int rv) { | 107 void ConnectJob::NotifyDelegateOfCompletion(int rv) { |
108 TRACE_EVENT0("net", "ConnectJob::NotifyDelegateOfCompletion"); | 108 TRACE_EVENT0("net", "ConnectJob::NotifyDelegateOfCompletion"); |
109 // The delegate will own |this|. | 109 // The delegate will own |this|. |
(...skipping 15 matching lines...) Expand all Loading... |
125 } | 125 } |
126 | 126 |
127 void ConnectJob::LogConnectCompletion(int net_error) { | 127 void ConnectJob::LogConnectCompletion(int net_error) { |
128 connect_timing_.connect_end = base::TimeTicks::Now(); | 128 connect_timing_.connect_end = base::TimeTicks::Now(); |
129 net_log().EndEventWithNetErrorCode( | 129 net_log().EndEventWithNetErrorCode( |
130 NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT, net_error); | 130 NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_CONNECT, net_error); |
131 } | 131 } |
132 | 132 |
133 void ConnectJob::OnTimeout() { | 133 void ConnectJob::OnTimeout() { |
134 // Make sure the socket is NULL before calling into |delegate|. | 134 // Make sure the socket is NULL before calling into |delegate|. |
135 SetSocket(scoped_ptr<StreamSocket>()); | 135 SetSocket(std::unique_ptr<StreamSocket>()); |
136 | 136 |
137 net_log_.AddEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT); | 137 net_log_.AddEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT); |
138 | 138 |
139 NotifyDelegateOfCompletion(ERR_TIMED_OUT); | 139 NotifyDelegateOfCompletion(ERR_TIMED_OUT); |
140 } | 140 } |
141 | 141 |
142 namespace internal { | 142 namespace internal { |
143 | 143 |
144 ClientSocketPoolBaseHelper::Request::Request( | 144 ClientSocketPoolBaseHelper::Request::Request( |
145 ClientSocketHandle* handle, | 145 ClientSocketHandle* handle, |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 | 272 |
273 void ClientSocketPoolBaseHelper::RemoveHigherLayeredPool( | 273 void ClientSocketPoolBaseHelper::RemoveHigherLayeredPool( |
274 HigherLayeredPool* higher_pool) { | 274 HigherLayeredPool* higher_pool) { |
275 CHECK(higher_pool); | 275 CHECK(higher_pool); |
276 CHECK(ContainsKey(higher_pools_, higher_pool)); | 276 CHECK(ContainsKey(higher_pools_, higher_pool)); |
277 higher_pools_.erase(higher_pool); | 277 higher_pools_.erase(higher_pool); |
278 } | 278 } |
279 | 279 |
280 int ClientSocketPoolBaseHelper::RequestSocket( | 280 int ClientSocketPoolBaseHelper::RequestSocket( |
281 const std::string& group_name, | 281 const std::string& group_name, |
282 scoped_ptr<const Request> request) { | 282 std::unique_ptr<const Request> request) { |
283 CHECK(!request->callback().is_null()); | 283 CHECK(!request->callback().is_null()); |
284 CHECK(request->handle()); | 284 CHECK(request->handle()); |
285 | 285 |
286 // Cleanup any timed-out idle sockets if no timer is used. | 286 // Cleanup any timed-out idle sockets if no timer is used. |
287 if (!use_cleanup_timer_) | 287 if (!use_cleanup_timer_) |
288 CleanupIdleSockets(false); | 288 CleanupIdleSockets(false); |
289 | 289 |
290 request->net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL); | 290 request->net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL); |
291 Group* group = GetOrCreateGroup(group_name); | 291 Group* group = GetOrCreateGroup(group_name); |
292 | 292 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 } else { | 409 } else { |
410 // We could check if we really have a stalled group here, but it requires | 410 // We could check if we really have a stalled group here, but it requires |
411 // a scan of all groups, so just flip a flag here, and do the check later. | 411 // a scan of all groups, so just flip a flag here, and do the check later. |
412 request.net_log().AddEvent(NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS); | 412 request.net_log().AddEvent(NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS); |
413 return ERR_IO_PENDING; | 413 return ERR_IO_PENDING; |
414 } | 414 } |
415 } | 415 } |
416 | 416 |
417 // We couldn't find a socket to reuse, and there's space to allocate one, | 417 // We couldn't find a socket to reuse, and there's space to allocate one, |
418 // so allocate and connect a new one. | 418 // so allocate and connect a new one. |
419 scoped_ptr<ConnectJob> connect_job( | 419 std::unique_ptr<ConnectJob> connect_job( |
420 connect_job_factory_->NewConnectJob(group_name, request, this)); | 420 connect_job_factory_->NewConnectJob(group_name, request, this)); |
421 | 421 |
422 int rv = connect_job->Connect(); | 422 int rv = connect_job->Connect(); |
423 if (rv == OK) { | 423 if (rv == OK) { |
424 LogBoundConnectJobToRequest(connect_job->net_log().source(), request); | 424 LogBoundConnectJobToRequest(connect_job->net_log().source(), request); |
425 if (!preconnecting) { | 425 if (!preconnecting) { |
426 HandOutSocket(connect_job->PassSocket(), ClientSocketHandle::UNUSED, | 426 HandOutSocket(connect_job->PassSocket(), ClientSocketHandle::UNUSED, |
427 connect_job->connect_timing(), handle, base::TimeDelta(), | 427 connect_job->connect_timing(), handle, base::TimeDelta(), |
428 group, request.net_log()); | 428 group, request.net_log()); |
429 } else { | 429 } else { |
430 AddIdleSocket(connect_job->PassSocket(), group); | 430 AddIdleSocket(connect_job->PassSocket(), group); |
431 } | 431 } |
432 } else if (rv == ERR_IO_PENDING) { | 432 } else if (rv == ERR_IO_PENDING) { |
433 // If we don't have any sockets in this group, set a timer for potentially | 433 // If we don't have any sockets in this group, set a timer for potentially |
434 // creating a new one. If the SYN is lost, this backup socket may complete | 434 // creating a new one. If the SYN is lost, this backup socket may complete |
435 // before the slow socket, improving end user latency. | 435 // before the slow socket, improving end user latency. |
436 if (connect_backup_jobs_enabled_ && group->IsEmpty()) { | 436 if (connect_backup_jobs_enabled_ && group->IsEmpty()) { |
437 group->StartBackupJobTimer(group_name, this); | 437 group->StartBackupJobTimer(group_name, this); |
438 } | 438 } |
439 | 439 |
440 connecting_socket_count_++; | 440 connecting_socket_count_++; |
441 | 441 |
442 group->AddJob(std::move(connect_job), preconnecting); | 442 group->AddJob(std::move(connect_job), preconnecting); |
443 } else { | 443 } else { |
444 LogBoundConnectJobToRequest(connect_job->net_log().source(), request); | 444 LogBoundConnectJobToRequest(connect_job->net_log().source(), request); |
445 scoped_ptr<StreamSocket> error_socket; | 445 std::unique_ptr<StreamSocket> error_socket; |
446 if (!preconnecting) { | 446 if (!preconnecting) { |
447 DCHECK(handle); | 447 DCHECK(handle); |
448 connect_job->GetAdditionalErrorState(handle); | 448 connect_job->GetAdditionalErrorState(handle); |
449 error_socket = connect_job->PassSocket(); | 449 error_socket = connect_job->PassSocket(); |
450 } | 450 } |
451 if (error_socket) { | 451 if (error_socket) { |
452 HandOutSocket(std::move(error_socket), ClientSocketHandle::UNUSED, | 452 HandOutSocket(std::move(error_socket), ClientSocketHandle::UNUSED, |
453 connect_job->connect_timing(), handle, base::TimeDelta(), | 453 connect_job->connect_timing(), handle, base::TimeDelta(), |
454 group, request.net_log()); | 454 group, request.net_log()); |
455 } else if (group->IsEmpty()) { | 455 } else if (group->IsEmpty()) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 ClientSocketHandle::SocketReuseType reuse_type = | 504 ClientSocketHandle::SocketReuseType reuse_type = |
505 idle_socket.socket->WasEverUsed() ? | 505 idle_socket.socket->WasEverUsed() ? |
506 ClientSocketHandle::REUSED_IDLE : | 506 ClientSocketHandle::REUSED_IDLE : |
507 ClientSocketHandle::UNUSED_IDLE; | 507 ClientSocketHandle::UNUSED_IDLE; |
508 | 508 |
509 // If this socket took multiple attempts to obtain, don't report those | 509 // If this socket took multiple attempts to obtain, don't report those |
510 // every time it's reused, just to the first user. | 510 // every time it's reused, just to the first user. |
511 if (idle_socket.socket->WasEverUsed()) | 511 if (idle_socket.socket->WasEverUsed()) |
512 idle_socket.socket->ClearConnectionAttempts(); | 512 idle_socket.socket->ClearConnectionAttempts(); |
513 | 513 |
514 HandOutSocket( | 514 HandOutSocket(std::unique_ptr<StreamSocket>(idle_socket.socket), reuse_type, |
515 scoped_ptr<StreamSocket>(idle_socket.socket), | 515 LoadTimingInfo::ConnectTiming(), request.handle(), idle_time, |
516 reuse_type, | 516 group, request.net_log()); |
517 LoadTimingInfo::ConnectTiming(), | |
518 request.handle(), | |
519 idle_time, | |
520 group, | |
521 request.net_log()); | |
522 return true; | 517 return true; |
523 } | 518 } |
524 | 519 |
525 return false; | 520 return false; |
526 } | 521 } |
527 | 522 |
528 // static | 523 // static |
529 void ClientSocketPoolBaseHelper::LogBoundConnectJobToRequest( | 524 void ClientSocketPoolBaseHelper::LogBoundConnectJobToRequest( |
530 const NetLog::Source& connect_job_source, const Request& request) { | 525 const NetLog::Source& connect_job_source, const Request& request) { |
531 request.net_log().AddEvent(NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB, | 526 request.net_log().AddEvent(NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB, |
532 connect_job_source.ToEventParametersCallback()); | 527 connect_job_source.ToEventParametersCallback()); |
533 } | 528 } |
534 | 529 |
535 void ClientSocketPoolBaseHelper::CancelRequest( | 530 void ClientSocketPoolBaseHelper::CancelRequest( |
536 const std::string& group_name, ClientSocketHandle* handle) { | 531 const std::string& group_name, ClientSocketHandle* handle) { |
537 PendingCallbackMap::iterator callback_it = pending_callback_map_.find(handle); | 532 PendingCallbackMap::iterator callback_it = pending_callback_map_.find(handle); |
538 if (callback_it != pending_callback_map_.end()) { | 533 if (callback_it != pending_callback_map_.end()) { |
539 int result = callback_it->second.result; | 534 int result = callback_it->second.result; |
540 pending_callback_map_.erase(callback_it); | 535 pending_callback_map_.erase(callback_it); |
541 scoped_ptr<StreamSocket> socket = handle->PassSocket(); | 536 std::unique_ptr<StreamSocket> socket = handle->PassSocket(); |
542 if (socket) { | 537 if (socket) { |
543 if (result != OK) | 538 if (result != OK) |
544 socket->Disconnect(); | 539 socket->Disconnect(); |
545 ReleaseSocket(handle->group_name(), std::move(socket), handle->id()); | 540 ReleaseSocket(handle->group_name(), std::move(socket), handle->id()); |
546 } | 541 } |
547 return; | 542 return; |
548 } | 543 } |
549 | 544 |
550 CHECK(ContainsKey(group_map_, group_name)); | 545 CHECK(ContainsKey(group_map_, group_name)); |
551 | 546 |
552 Group* group = GetOrCreateGroup(group_name); | 547 Group* group = GetOrCreateGroup(group_name); |
553 | 548 |
554 // Search pending_requests for matching handle. | 549 // Search pending_requests for matching handle. |
555 scoped_ptr<const Request> request = | 550 std::unique_ptr<const Request> request = |
556 group->FindAndRemovePendingRequest(handle); | 551 group->FindAndRemovePendingRequest(handle); |
557 if (request) { | 552 if (request) { |
558 request->net_log().AddEvent(NetLog::TYPE_CANCELLED); | 553 request->net_log().AddEvent(NetLog::TYPE_CANCELLED); |
559 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); | 554 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); |
560 | 555 |
561 // We let the job run, unless we're at the socket limit and there is | 556 // We let the job run, unless we're at the socket limit and there is |
562 // not another request waiting on the job. | 557 // not another request waiting on the job. |
563 if (group->jobs().size() > group->pending_request_count() && | 558 if (group->jobs().size() > group->pending_request_count() && |
564 ReachedMaxSocketsLimit()) { | 559 ReachedMaxSocketsLimit()) { |
565 RemoveConnectJob(*group->jobs().begin(), group); | 560 RemoveConnectJob(*group->jobs().begin(), group); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 if (group.HasConnectJobForHandle(handle)) { | 599 if (group.HasConnectJobForHandle(handle)) { |
605 // Just return the state of the oldest ConnectJob. | 600 // Just return the state of the oldest ConnectJob. |
606 return (*group.jobs().begin())->GetLoadState(); | 601 return (*group.jobs().begin())->GetLoadState(); |
607 } | 602 } |
608 | 603 |
609 if (group.CanUseAdditionalSocketSlot(max_sockets_per_group_)) | 604 if (group.CanUseAdditionalSocketSlot(max_sockets_per_group_)) |
610 return LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL; | 605 return LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL; |
611 return LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET; | 606 return LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET; |
612 } | 607 } |
613 | 608 |
614 scoped_ptr<base::DictionaryValue> ClientSocketPoolBaseHelper::GetInfoAsValue( | 609 std::unique_ptr<base::DictionaryValue> |
615 const std::string& name, const std::string& type) const { | 610 ClientSocketPoolBaseHelper::GetInfoAsValue(const std::string& name, |
616 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | 611 const std::string& type) const { |
| 612 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); |
617 dict->SetString("name", name); | 613 dict->SetString("name", name); |
618 dict->SetString("type", type); | 614 dict->SetString("type", type); |
619 dict->SetInteger("handed_out_socket_count", handed_out_socket_count_); | 615 dict->SetInteger("handed_out_socket_count", handed_out_socket_count_); |
620 dict->SetInteger("connecting_socket_count", connecting_socket_count_); | 616 dict->SetInteger("connecting_socket_count", connecting_socket_count_); |
621 dict->SetInteger("idle_socket_count", idle_socket_count_); | 617 dict->SetInteger("idle_socket_count", idle_socket_count_); |
622 dict->SetInteger("max_socket_count", max_sockets_); | 618 dict->SetInteger("max_socket_count", max_sockets_); |
623 dict->SetInteger("max_sockets_per_group", max_sockets_per_group_); | 619 dict->SetInteger("max_sockets_per_group", max_sockets_per_group_); |
624 dict->SetInteger("pool_generation_number", pool_generation_number_); | 620 dict->SetInteger("pool_generation_number", pool_generation_number_); |
625 | 621 |
626 if (group_map_.empty()) | 622 if (group_map_.empty()) |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 bool old_value = g_cleanup_timer_enabled; | 775 bool old_value = g_cleanup_timer_enabled; |
780 g_cleanup_timer_enabled = enabled; | 776 g_cleanup_timer_enabled = enabled; |
781 return old_value; | 777 return old_value; |
782 } | 778 } |
783 | 779 |
784 void ClientSocketPoolBaseHelper::StartIdleSocketTimer() { | 780 void ClientSocketPoolBaseHelper::StartIdleSocketTimer() { |
785 timer_.Start(FROM_HERE, TimeDelta::FromSeconds(kCleanupInterval), this, | 781 timer_.Start(FROM_HERE, TimeDelta::FromSeconds(kCleanupInterval), this, |
786 &ClientSocketPoolBaseHelper::OnCleanupTimerFired); | 782 &ClientSocketPoolBaseHelper::OnCleanupTimerFired); |
787 } | 783 } |
788 | 784 |
789 void ClientSocketPoolBaseHelper::ReleaseSocket(const std::string& group_name, | 785 void ClientSocketPoolBaseHelper::ReleaseSocket( |
790 scoped_ptr<StreamSocket> socket, | 786 const std::string& group_name, |
791 int id) { | 787 std::unique_ptr<StreamSocket> socket, |
| 788 int id) { |
792 GroupMap::iterator i = group_map_.find(group_name); | 789 GroupMap::iterator i = group_map_.find(group_name); |
793 CHECK(i != group_map_.end()); | 790 CHECK(i != group_map_.end()); |
794 | 791 |
795 Group* group = i->second; | 792 Group* group = i->second; |
796 | 793 |
797 CHECK_GT(handed_out_socket_count_, 0); | 794 CHECK_GT(handed_out_socket_count_, 0); |
798 handed_out_socket_count_--; | 795 handed_out_socket_count_--; |
799 | 796 |
800 CHECK_GT(group->active_socket_count(), 0); | 797 CHECK_GT(group->active_socket_count(), 0); |
801 group->DecrementActiveSocketCount(); | 798 group->DecrementActiveSocketCount(); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
887 } | 884 } |
888 | 885 |
889 void ClientSocketPoolBaseHelper::OnConnectJobComplete( | 886 void ClientSocketPoolBaseHelper::OnConnectJobComplete( |
890 int result, ConnectJob* job) { | 887 int result, ConnectJob* job) { |
891 DCHECK_NE(ERR_IO_PENDING, result); | 888 DCHECK_NE(ERR_IO_PENDING, result); |
892 const std::string group_name = job->group_name(); | 889 const std::string group_name = job->group_name(); |
893 GroupMap::iterator group_it = group_map_.find(group_name); | 890 GroupMap::iterator group_it = group_map_.find(group_name); |
894 CHECK(group_it != group_map_.end()); | 891 CHECK(group_it != group_map_.end()); |
895 Group* group = group_it->second; | 892 Group* group = group_it->second; |
896 | 893 |
897 scoped_ptr<StreamSocket> socket = job->PassSocket(); | 894 std::unique_ptr<StreamSocket> socket = job->PassSocket(); |
898 | 895 |
899 // Copies of these are needed because |job| may be deleted before they are | 896 // Copies of these are needed because |job| may be deleted before they are |
900 // accessed. | 897 // accessed. |
901 BoundNetLog job_log = job->net_log(); | 898 BoundNetLog job_log = job->net_log(); |
902 LoadTimingInfo::ConnectTiming connect_timing = job->connect_timing(); | 899 LoadTimingInfo::ConnectTiming connect_timing = job->connect_timing(); |
903 | 900 |
904 // RemoveConnectJob(job, _) must be called by all branches below; | 901 // RemoveConnectJob(job, _) must be called by all branches below; |
905 // otherwise, |job| will be leaked. | 902 // otherwise, |job| will be leaked. |
906 | 903 |
907 if (result == OK) { | 904 if (result == OK) { |
908 DCHECK(socket.get()); | 905 DCHECK(socket.get()); |
909 RemoveConnectJob(job, group); | 906 RemoveConnectJob(job, group); |
910 scoped_ptr<const Request> request = group->PopNextPendingRequest(); | 907 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); |
911 if (request) { | 908 if (request) { |
912 LogBoundConnectJobToRequest(job_log.source(), *request); | 909 LogBoundConnectJobToRequest(job_log.source(), *request); |
913 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, | 910 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, |
914 connect_timing, request->handle(), base::TimeDelta(), group, | 911 connect_timing, request->handle(), base::TimeDelta(), group, |
915 request->net_log()); | 912 request->net_log()); |
916 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); | 913 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); |
917 InvokeUserCallbackLater(request->handle(), request->callback(), result); | 914 InvokeUserCallbackLater(request->handle(), request->callback(), result); |
918 } else { | 915 } else { |
919 AddIdleSocket(std::move(socket), group); | 916 AddIdleSocket(std::move(socket), group); |
920 OnAvailableSocketSlot(group_name, group); | 917 OnAvailableSocketSlot(group_name, group); |
921 CheckForStalledSocketGroups(); | 918 CheckForStalledSocketGroups(); |
922 } | 919 } |
923 } else { | 920 } else { |
924 // If we got a socket, it must contain error information so pass that | 921 // If we got a socket, it must contain error information so pass that |
925 // up so that the caller can retrieve it. | 922 // up so that the caller can retrieve it. |
926 bool handed_out_socket = false; | 923 bool handed_out_socket = false; |
927 scoped_ptr<const Request> request = group->PopNextPendingRequest(); | 924 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); |
928 if (request) { | 925 if (request) { |
929 LogBoundConnectJobToRequest(job_log.source(), *request); | 926 LogBoundConnectJobToRequest(job_log.source(), *request); |
930 job->GetAdditionalErrorState(request->handle()); | 927 job->GetAdditionalErrorState(request->handle()); |
931 RemoveConnectJob(job, group); | 928 RemoveConnectJob(job, group); |
932 if (socket.get()) { | 929 if (socket.get()) { |
933 handed_out_socket = true; | 930 handed_out_socket = true; |
934 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, | 931 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, |
935 connect_timing, request->handle(), base::TimeDelta(), | 932 connect_timing, request->handle(), base::TimeDelta(), |
936 group, request->net_log()); | 933 group, request->net_log()); |
937 } | 934 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
986 // If the group has no idle sockets, and can't make use of an additional slot, | 983 // If the group has no idle sockets, and can't make use of an additional slot, |
987 // either because it's at the limit or because it's at the socket per group | 984 // either because it's at the limit or because it's at the socket per group |
988 // limit, then there's nothing to do. | 985 // limit, then there's nothing to do. |
989 if (group->idle_sockets().empty() && | 986 if (group->idle_sockets().empty() && |
990 !group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) { | 987 !group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) { |
991 return; | 988 return; |
992 } | 989 } |
993 | 990 |
994 int rv = RequestSocketInternal(group_name, *next_request); | 991 int rv = RequestSocketInternal(group_name, *next_request); |
995 if (rv != ERR_IO_PENDING) { | 992 if (rv != ERR_IO_PENDING) { |
996 scoped_ptr<const Request> request = group->PopNextPendingRequest(); | 993 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); |
997 DCHECK(request); | 994 DCHECK(request); |
998 if (group->IsEmpty()) | 995 if (group->IsEmpty()) |
999 RemoveGroup(group_name); | 996 RemoveGroup(group_name); |
1000 | 997 |
1001 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); | 998 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); |
1002 InvokeUserCallbackLater(request->handle(), request->callback(), rv); | 999 InvokeUserCallbackLater(request->handle(), request->callback(), rv); |
1003 } | 1000 } |
1004 } | 1001 } |
1005 | 1002 |
1006 void ClientSocketPoolBaseHelper::HandOutSocket( | 1003 void ClientSocketPoolBaseHelper::HandOutSocket( |
1007 scoped_ptr<StreamSocket> socket, | 1004 std::unique_ptr<StreamSocket> socket, |
1008 ClientSocketHandle::SocketReuseType reuse_type, | 1005 ClientSocketHandle::SocketReuseType reuse_type, |
1009 const LoadTimingInfo::ConnectTiming& connect_timing, | 1006 const LoadTimingInfo::ConnectTiming& connect_timing, |
1010 ClientSocketHandle* handle, | 1007 ClientSocketHandle* handle, |
1011 base::TimeDelta idle_time, | 1008 base::TimeDelta idle_time, |
1012 Group* group, | 1009 Group* group, |
1013 const BoundNetLog& net_log) { | 1010 const BoundNetLog& net_log) { |
1014 DCHECK(socket); | 1011 DCHECK(socket); |
1015 handle->SetSocket(std::move(socket)); | 1012 handle->SetSocket(std::move(socket)); |
1016 handle->set_reuse_type(reuse_type); | 1013 handle->set_reuse_type(reuse_type); |
1017 handle->set_idle_time(idle_time); | 1014 handle->set_idle_time(idle_time); |
1018 handle->set_pool_id(pool_generation_number_); | 1015 handle->set_pool_id(pool_generation_number_); |
1019 handle->set_connect_timing(connect_timing); | 1016 handle->set_connect_timing(connect_timing); |
1020 | 1017 |
1021 if (handle->is_reused()) { | 1018 if (handle->is_reused()) { |
1022 net_log.AddEvent( | 1019 net_log.AddEvent( |
1023 NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET, | 1020 NetLog::TYPE_SOCKET_POOL_REUSED_AN_EXISTING_SOCKET, |
1024 NetLog::IntCallback("idle_ms", | 1021 NetLog::IntCallback("idle_ms", |
1025 static_cast<int>(idle_time.InMilliseconds()))); | 1022 static_cast<int>(idle_time.InMilliseconds()))); |
1026 } | 1023 } |
1027 | 1024 |
1028 net_log.AddEvent( | 1025 net_log.AddEvent( |
1029 NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET, | 1026 NetLog::TYPE_SOCKET_POOL_BOUND_TO_SOCKET, |
1030 handle->socket()->NetLog().source().ToEventParametersCallback()); | 1027 handle->socket()->NetLog().source().ToEventParametersCallback()); |
1031 | 1028 |
1032 handed_out_socket_count_++; | 1029 handed_out_socket_count_++; |
1033 group->IncrementActiveSocketCount(); | 1030 group->IncrementActiveSocketCount(); |
1034 } | 1031 } |
1035 | 1032 |
1036 void ClientSocketPoolBaseHelper::AddIdleSocket( | 1033 void ClientSocketPoolBaseHelper::AddIdleSocket( |
1037 scoped_ptr<StreamSocket> socket, | 1034 std::unique_ptr<StreamSocket> socket, |
1038 Group* group) { | 1035 Group* group) { |
1039 DCHECK(socket); | 1036 DCHECK(socket); |
1040 IdleSocket idle_socket; | 1037 IdleSocket idle_socket; |
1041 idle_socket.socket = socket.release(); | 1038 idle_socket.socket = socket.release(); |
1042 idle_socket.start_time = base::TimeTicks::Now(); | 1039 idle_socket.start_time = base::TimeTicks::Now(); |
1043 | 1040 |
1044 group->mutable_idle_sockets()->push_back(idle_socket); | 1041 group->mutable_idle_sockets()->push_back(idle_socket); |
1045 IncrementIdleCount(); | 1042 IncrementIdleCount(); |
1046 } | 1043 } |
1047 | 1044 |
(...skipping 14 matching lines...) Expand all Loading... |
1062 } | 1059 } |
1063 } | 1060 } |
1064 DCHECK_EQ(0, connecting_socket_count_); | 1061 DCHECK_EQ(0, connecting_socket_count_); |
1065 } | 1062 } |
1066 | 1063 |
1067 void ClientSocketPoolBaseHelper::CancelAllRequestsWithError(int error) { | 1064 void ClientSocketPoolBaseHelper::CancelAllRequestsWithError(int error) { |
1068 for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end();) { | 1065 for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end();) { |
1069 Group* group = i->second; | 1066 Group* group = i->second; |
1070 | 1067 |
1071 while (true) { | 1068 while (true) { |
1072 scoped_ptr<const Request> request = group->PopNextPendingRequest(); | 1069 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); |
1073 if (!request) | 1070 if (!request) |
1074 break; | 1071 break; |
1075 InvokeUserCallbackLater(request->handle(), request->callback(), error); | 1072 InvokeUserCallbackLater(request->handle(), request->callback(), error); |
1076 } | 1073 } |
1077 | 1074 |
1078 // Delete group if no longer needed. | 1075 // Delete group if no longer needed. |
1079 if (group->IsEmpty()) { | 1076 if (group->IsEmpty()) { |
1080 // RemoveGroup() will call .erase() which will invalidate the iterator, | 1077 // RemoveGroup() will call .erase() which will invalidate the iterator, |
1081 // but i will already have been incremented to a valid iterator before | 1078 // but i will already have been incremented to a valid iterator before |
1082 // RemoveGroup() is called. | 1079 // RemoveGroup() is called. |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 | 1200 |
1204 bool ClientSocketPoolBaseHelper::Group::TryToUseUnassignedConnectJob() { | 1201 bool ClientSocketPoolBaseHelper::Group::TryToUseUnassignedConnectJob() { |
1205 SanityCheck(); | 1202 SanityCheck(); |
1206 | 1203 |
1207 if (unassigned_job_count_ == 0) | 1204 if (unassigned_job_count_ == 0) |
1208 return false; | 1205 return false; |
1209 --unassigned_job_count_; | 1206 --unassigned_job_count_; |
1210 return true; | 1207 return true; |
1211 } | 1208 } |
1212 | 1209 |
1213 void ClientSocketPoolBaseHelper::Group::AddJob(scoped_ptr<ConnectJob> job, | 1210 void ClientSocketPoolBaseHelper::Group::AddJob(std::unique_ptr<ConnectJob> job, |
1214 bool is_preconnect) { | 1211 bool is_preconnect) { |
1215 SanityCheck(); | 1212 SanityCheck(); |
1216 | 1213 |
1217 if (is_preconnect) | 1214 if (is_preconnect) |
1218 ++unassigned_job_count_; | 1215 ++unassigned_job_count_; |
1219 jobs_.push_back(job.release()); | 1216 jobs_.push_back(job.release()); |
1220 } | 1217 } |
1221 | 1218 |
1222 void ClientSocketPoolBaseHelper::Group::RemoveJob(ConnectJob* job) { | 1219 void ClientSocketPoolBaseHelper::Group::RemoveJob(ConnectJob* job) { |
1223 scoped_ptr<ConnectJob> owned_job(job); | 1220 std::unique_ptr<ConnectJob> owned_job(job); |
1224 SanityCheck(); | 1221 SanityCheck(); |
1225 | 1222 |
1226 // Check that |job| is in the list. | 1223 // Check that |job| is in the list. |
1227 DCHECK_EQ(*std::find(jobs_.begin(), jobs_.end(), job), job); | 1224 DCHECK_EQ(*std::find(jobs_.begin(), jobs_.end(), job), job); |
1228 jobs_.remove(job); | 1225 jobs_.remove(job); |
1229 size_t job_count = jobs_.size(); | 1226 size_t job_count = jobs_.size(); |
1230 if (job_count < unassigned_job_count_) | 1227 if (job_count < unassigned_job_count_) |
1231 unassigned_job_count_ = job_count; | 1228 unassigned_job_count_ = job_count; |
1232 | 1229 |
1233 // If we've got no more jobs for this group, then we no longer need a | 1230 // If we've got no more jobs for this group, then we no longer need a |
(...skipping 17 matching lines...) Expand all Loading... |
1251 if (pool->ReachedMaxSocketsLimit() || | 1248 if (pool->ReachedMaxSocketsLimit() || |
1252 !HasAvailableSocketSlot(pool->max_sockets_per_group_) || | 1249 !HasAvailableSocketSlot(pool->max_sockets_per_group_) || |
1253 (*jobs_.begin())->GetLoadState() == LOAD_STATE_RESOLVING_HOST) { | 1250 (*jobs_.begin())->GetLoadState() == LOAD_STATE_RESOLVING_HOST) { |
1254 StartBackupJobTimer(group_name, pool); | 1251 StartBackupJobTimer(group_name, pool); |
1255 return; | 1252 return; |
1256 } | 1253 } |
1257 | 1254 |
1258 if (pending_requests_.empty()) | 1255 if (pending_requests_.empty()) |
1259 return; | 1256 return; |
1260 | 1257 |
1261 scoped_ptr<ConnectJob> backup_job = | 1258 std::unique_ptr<ConnectJob> backup_job = |
1262 pool->connect_job_factory_->NewConnectJob( | 1259 pool->connect_job_factory_->NewConnectJob( |
1263 group_name, *pending_requests_.FirstMax().value(), pool); | 1260 group_name, *pending_requests_.FirstMax().value(), pool); |
1264 backup_job->net_log().AddEvent(NetLog::TYPE_BACKUP_CONNECT_JOB_CREATED); | 1261 backup_job->net_log().AddEvent(NetLog::TYPE_BACKUP_CONNECT_JOB_CREATED); |
1265 int rv = backup_job->Connect(); | 1262 int rv = backup_job->Connect(); |
1266 pool->connecting_socket_count_++; | 1263 pool->connecting_socket_count_++; |
1267 ConnectJob* raw_backup_job = backup_job.get(); | 1264 ConnectJob* raw_backup_job = backup_job.get(); |
1268 AddJob(std::move(backup_job), false); | 1265 AddJob(std::move(backup_job), false); |
1269 if (rv != ERR_IO_PENDING) | 1266 if (rv != ERR_IO_PENDING) |
1270 pool->OnConnectJobComplete(rv, raw_backup_job); | 1267 pool->OnConnectJobComplete(rv, raw_backup_job); |
1271 } | 1268 } |
(...skipping 28 matching lines...) Expand all Loading... |
1300 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); | 1297 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); |
1301 !pointer.is_null() && i < jobs_.size(); | 1298 !pointer.is_null() && i < jobs_.size(); |
1302 pointer = pending_requests_.GetNextTowardsLastMin(pointer), ++i) { | 1299 pointer = pending_requests_.GetNextTowardsLastMin(pointer), ++i) { |
1303 if (pointer.value()->handle() == handle) | 1300 if (pointer.value()->handle() == handle) |
1304 return true; | 1301 return true; |
1305 } | 1302 } |
1306 return false; | 1303 return false; |
1307 } | 1304 } |
1308 | 1305 |
1309 void ClientSocketPoolBaseHelper::Group::InsertPendingRequest( | 1306 void ClientSocketPoolBaseHelper::Group::InsertPendingRequest( |
1310 scoped_ptr<const Request> request) { | 1307 std::unique_ptr<const Request> request) { |
1311 // This value must be cached before we release |request|. | 1308 // This value must be cached before we release |request|. |
1312 RequestPriority priority = request->priority(); | 1309 RequestPriority priority = request->priority(); |
1313 if (request->respect_limits() == ClientSocketPool::RespectLimits::DISABLED) { | 1310 if (request->respect_limits() == ClientSocketPool::RespectLimits::DISABLED) { |
1314 // Put requests with RespectLimits::DISABLED (which should have | 1311 // Put requests with RespectLimits::DISABLED (which should have |
1315 // priority == MAXIMUM_PRIORITY) ahead of other requests with | 1312 // priority == MAXIMUM_PRIORITY) ahead of other requests with |
1316 // MAXIMUM_PRIORITY. | 1313 // MAXIMUM_PRIORITY. |
1317 DCHECK_EQ(priority, MAXIMUM_PRIORITY); | 1314 DCHECK_EQ(priority, MAXIMUM_PRIORITY); |
1318 pending_requests_.InsertAtFront(request.release(), priority); | 1315 pending_requests_.InsertAtFront(request.release(), priority); |
1319 } else { | 1316 } else { |
1320 pending_requests_.Insert(request.release(), priority); | 1317 pending_requests_.Insert(request.release(), priority); |
1321 } | 1318 } |
1322 } | 1319 } |
1323 | 1320 |
1324 scoped_ptr<const ClientSocketPoolBaseHelper::Request> | 1321 std::unique_ptr<const ClientSocketPoolBaseHelper::Request> |
1325 ClientSocketPoolBaseHelper::Group::PopNextPendingRequest() { | 1322 ClientSocketPoolBaseHelper::Group::PopNextPendingRequest() { |
1326 if (pending_requests_.empty()) | 1323 if (pending_requests_.empty()) |
1327 return scoped_ptr<const ClientSocketPoolBaseHelper::Request>(); | 1324 return std::unique_ptr<const ClientSocketPoolBaseHelper::Request>(); |
1328 return RemovePendingRequest(pending_requests_.FirstMax()); | 1325 return RemovePendingRequest(pending_requests_.FirstMax()); |
1329 } | 1326 } |
1330 | 1327 |
1331 scoped_ptr<const ClientSocketPoolBaseHelper::Request> | 1328 std::unique_ptr<const ClientSocketPoolBaseHelper::Request> |
1332 ClientSocketPoolBaseHelper::Group::FindAndRemovePendingRequest( | 1329 ClientSocketPoolBaseHelper::Group::FindAndRemovePendingRequest( |
1333 ClientSocketHandle* handle) { | 1330 ClientSocketHandle* handle) { |
1334 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); | 1331 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); |
1335 !pointer.is_null(); | 1332 !pointer.is_null(); |
1336 pointer = pending_requests_.GetNextTowardsLastMin(pointer)) { | 1333 pointer = pending_requests_.GetNextTowardsLastMin(pointer)) { |
1337 if (pointer.value()->handle() == handle) { | 1334 if (pointer.value()->handle() == handle) { |
1338 scoped_ptr<const Request> request = RemovePendingRequest(pointer); | 1335 std::unique_ptr<const Request> request = RemovePendingRequest(pointer); |
1339 return request; | 1336 return request; |
1340 } | 1337 } |
1341 } | 1338 } |
1342 return scoped_ptr<const ClientSocketPoolBaseHelper::Request>(); | 1339 return std::unique_ptr<const ClientSocketPoolBaseHelper::Request>(); |
1343 } | 1340 } |
1344 | 1341 |
1345 scoped_ptr<const ClientSocketPoolBaseHelper::Request> | 1342 std::unique_ptr<const ClientSocketPoolBaseHelper::Request> |
1346 ClientSocketPoolBaseHelper::Group::RemovePendingRequest( | 1343 ClientSocketPoolBaseHelper::Group::RemovePendingRequest( |
1347 const RequestQueue::Pointer& pointer) { | 1344 const RequestQueue::Pointer& pointer) { |
1348 // TODO(eroman): Temporary for debugging http://crbug.com/467797. | 1345 // TODO(eroman): Temporary for debugging http://crbug.com/467797. |
1349 CHECK(!pointer.is_null()); | 1346 CHECK(!pointer.is_null()); |
1350 scoped_ptr<const Request> request(pointer.value()); | 1347 std::unique_ptr<const Request> request(pointer.value()); |
1351 pending_requests_.Erase(pointer); | 1348 pending_requests_.Erase(pointer); |
1352 // If there are no more requests, kill the backup timer. | 1349 // If there are no more requests, kill the backup timer. |
1353 if (pending_requests_.empty()) | 1350 if (pending_requests_.empty()) |
1354 backup_job_timer_.Stop(); | 1351 backup_job_timer_.Stop(); |
1355 request->CrashIfInvalid(); | 1352 request->CrashIfInvalid(); |
1356 return request; | 1353 return request; |
1357 } | 1354 } |
1358 | 1355 |
1359 } // namespace internal | 1356 } // namespace internal |
1360 | 1357 |
1361 } // namespace net | 1358 } // namespace net |
OLD | NEW |