| 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 |