Commit 105a6a1b authored by Matt Menke's avatar Matt Menke Committed by Commit Bot

Socket Pools Refactor 29: Rework HTTP proxy auth (part 3).

This CL renames "pending" requests in ClientSocketPoolBase::Request to
"unbound" requests, after the introduction of the notion of "bound" in
https://chromium-review.googlesource.com/c/chromium/src/+/1481900

This is a separate CL to keep the CL it's on top of more focused.

This is part of an effort to flatten the socket pools.
https://docs.google.com/document/d/1g0EA4iDqaDhNXA_mq-YK3SlSX-xRkoKvZetAQqdRrxM/edit

Bug: 472729
Change-Id: I9ed0e4e4cd5e87be2d2b032fdd98313f420a621b
Reviewed-on: https://chromium-review.googlesource.com/c/1487791
Commit-Queue: Matt Menke <mmenke@chromium.org>
Reviewed-by: default avatarAsanka Herath <asanka@chromium.org>
Cr-Commit-Position: refs/heads/master@{#636887}
parent 15f3437d
...@@ -220,7 +220,7 @@ int ClientSocketPoolBaseHelper::RequestSocket( ...@@ -220,7 +220,7 @@ int ClientSocketPoolBaseHelper::RequestSocket(
request.reset(); request.reset();
} else { } else {
Group* group = GetOrCreateGroup(group_name); Group* group = GetOrCreateGroup(group_name);
group->InsertPendingRequest(std::move(request)); group->InsertUnboundRequest(std::move(request));
// Have to do this asynchronously, as closing sockets in higher level pools // Have to do this asynchronously, as closing sockets in higher level pools
// call back in to |this|, which will cause all sorts of fun and exciting // call back in to |this|, which will cause all sorts of fun and exciting
// re-entrancy issues if the socket pool is doing something else at the // re-entrancy issues if the socket pool is doing something else at the
...@@ -503,15 +503,15 @@ void ClientSocketPoolBaseHelper::CancelRequest( ...@@ -503,15 +503,15 @@ void ClientSocketPoolBaseHelper::CancelRequest(
return; return;
} }
// Search pending_requests for matching handle. // Search |unbound_requests_| for matching handle.
request = group->FindAndRemovePendingRequest(handle); request = group->FindAndRemoveUnboundRequest(handle);
if (request) { if (request) {
request->net_log().AddEvent(NetLogEventType::CANCELLED); request->net_log().AddEvent(NetLogEventType::CANCELLED);
request->net_log().EndEvent(NetLogEventType::SOCKET_POOL); request->net_log().EndEvent(NetLogEventType::SOCKET_POOL);
// We let the job run, unless we're at the socket limit and there is // We let the job run, unless we're at the socket limit and there is
// not another request waiting on the job. // not another request waiting on the job.
if (group->jobs().size() > group->pending_request_count() && if (group->jobs().size() > group->unbound_request_count() &&
ReachedMaxSocketsLimit()) { ReachedMaxSocketsLimit()) {
RemoveConnectJob(group->jobs().begin()->get(), group); RemoveConnectJob(group->jobs().begin()->get(), group);
CheckForStalledSocketGroups(); CheckForStalledSocketGroups();
...@@ -597,8 +597,8 @@ ClientSocketPoolBaseHelper::GetInfoAsValue(const std::string& name, ...@@ -597,8 +597,8 @@ ClientSocketPoolBaseHelper::GetInfoAsValue(const std::string& name,
auto group_dict = std::make_unique<base::DictionaryValue>(); auto group_dict = std::make_unique<base::DictionaryValue>();
group_dict->SetInteger("pending_request_count", group_dict->SetInteger("pending_request_count",
group->pending_request_count()); group->unbound_request_count());
if (group->has_pending_requests()) { if (group->has_unbound_requests()) {
group_dict->SetString( group_dict->SetString(
"top_pending_priority", "top_pending_priority",
RequestPriorityToString(group->TopPendingPriority())); RequestPriorityToString(group->TopPendingPriority()));
...@@ -843,7 +843,7 @@ bool ClientSocketPoolBaseHelper::FindTopStalledGroup( ...@@ -843,7 +843,7 @@ bool ClientSocketPoolBaseHelper::FindTopStalledGroup(
bool has_stalled_group = false; bool has_stalled_group = false;
for (auto i = group_map_.begin(); i != group_map_.end(); ++i) { for (auto i = group_map_.begin(); i != group_map_.end(); ++i) {
Group* curr_group = i->second; Group* curr_group = i->second;
if (!curr_group->has_pending_requests()) if (!curr_group->has_unbound_requests())
continue; continue;
if (curr_group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) { if (curr_group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) {
if (!group) if (!group)
...@@ -920,7 +920,7 @@ void ClientSocketPoolBaseHelper::OnConnectJobComplete( ...@@ -920,7 +920,7 @@ void ClientSocketPoolBaseHelper::OnConnectJobComplete(
if (result == OK) { if (result == OK) {
DCHECK(socket.get()); DCHECK(socket.get());
request = group->PopNextPendingRequest(); request = group->PopNextUnboundRequest();
RemoveConnectJob(job, group); RemoveConnectJob(job, group);
if (request) { if (request) {
LogBoundConnectJobToRequest(job_log.source(), *request); LogBoundConnectJobToRequest(job_log.source(), *request);
...@@ -939,7 +939,7 @@ void ClientSocketPoolBaseHelper::OnConnectJobComplete( ...@@ -939,7 +939,7 @@ void ClientSocketPoolBaseHelper::OnConnectJobComplete(
// If we got a socket, it must contain error information so pass that // If we got a socket, it must contain error information so pass that
// up so that the caller can retrieve it. // up so that the caller can retrieve it.
bool handed_out_socket = false; bool handed_out_socket = false;
std::unique_ptr<Request> request = group->PopNextPendingRequest(); std::unique_ptr<Request> request = group->PopNextUnboundRequest();
if (request) { if (request) {
LogBoundConnectJobToRequest(job_log.source(), *request); LogBoundConnectJobToRequest(job_log.source(), *request);
job->GetAdditionalErrorState(request->handle()); job->GetAdditionalErrorState(request->handle());
...@@ -1001,7 +1001,7 @@ void ClientSocketPoolBaseHelper::RemoveConnectJob(ConnectJob* job, ...@@ -1001,7 +1001,7 @@ void ClientSocketPoolBaseHelper::RemoveConnectJob(ConnectJob* job,
connecting_socket_count_--; connecting_socket_count_--;
DCHECK(group); DCHECK(group);
group->RemoveJob(job); group->RemoveUnboundJob(job);
} }
void ClientSocketPoolBaseHelper::OnAvailableSocketSlot( void ClientSocketPoolBaseHelper::OnAvailableSocketSlot(
...@@ -1009,14 +1009,14 @@ void ClientSocketPoolBaseHelper::OnAvailableSocketSlot( ...@@ -1009,14 +1009,14 @@ void ClientSocketPoolBaseHelper::OnAvailableSocketSlot(
DCHECK(base::ContainsKey(group_map_, group_name)); DCHECK(base::ContainsKey(group_map_, group_name));
if (group->IsEmpty()) { if (group->IsEmpty()) {
RemoveGroup(group_name); RemoveGroup(group_name);
} else if (group->has_pending_requests()) { } else if (group->has_unbound_requests()) {
ProcessPendingRequest(group_name, group); ProcessPendingRequest(group_name, group);
} }
} }
void ClientSocketPoolBaseHelper::ProcessPendingRequest( void ClientSocketPoolBaseHelper::ProcessPendingRequest(
const std::string& group_name, Group* group) { const std::string& group_name, Group* group) {
const Request* next_request = group->GetNextPendingRequest(); const Request* next_request = group->GetNextUnboundRequest();
DCHECK(next_request); DCHECK(next_request);
// If the group has no idle sockets, and can't make use of an additional slot, // If the group has no idle sockets, and can't make use of an additional slot,
...@@ -1029,7 +1029,7 @@ void ClientSocketPoolBaseHelper::ProcessPendingRequest( ...@@ -1029,7 +1029,7 @@ void ClientSocketPoolBaseHelper::ProcessPendingRequest(
int rv = RequestSocketInternal(group_name, *next_request); int rv = RequestSocketInternal(group_name, *next_request);
if (rv != ERR_IO_PENDING) { if (rv != ERR_IO_PENDING) {
std::unique_ptr<Request> request = group->PopNextPendingRequest(); std::unique_ptr<Request> request = group->PopNextUnboundRequest();
DCHECK(request); DCHECK(request);
if (group->IsEmpty()) if (group->IsEmpty())
RemoveGroup(group_name); RemoveGroup(group_name);
...@@ -1094,7 +1094,7 @@ void ClientSocketPoolBaseHelper::CancelAllConnectJobs() { ...@@ -1094,7 +1094,7 @@ void ClientSocketPoolBaseHelper::CancelAllConnectJobs() {
for (auto i = group_map_.begin(); i != group_map_.end();) { for (auto i = group_map_.begin(); i != group_map_.end();) {
Group* group = i->second; Group* group = i->second;
connecting_socket_count_ -= group->jobs().size(); connecting_socket_count_ -= group->jobs().size();
group->RemoveAllJobs(); group->RemoveAllUnboundJobs();
// Delete group if no longer needed. // Delete group if no longer needed.
if (group->IsEmpty()) { if (group->IsEmpty()) {
...@@ -1111,7 +1111,7 @@ void ClientSocketPoolBaseHelper::CancelAllRequestsWithError(int error) { ...@@ -1111,7 +1111,7 @@ void ClientSocketPoolBaseHelper::CancelAllRequestsWithError(int error) {
Group* group = i->second; Group* group = i->second;
while (true) { while (true) {
std::unique_ptr<Request> request = group->PopNextPendingRequest(); std::unique_ptr<Request> request = group->PopNextUnboundRequest();
if (!request) if (!request)
break; break;
InvokeUserCallbackLater(request->handle(), request->release_callback(), InvokeUserCallbackLater(request->handle(), request->release_callback(),
...@@ -1228,13 +1228,13 @@ void ClientSocketPoolBaseHelper::TryToCloseSocketsInLayeredPools() { ...@@ -1228,13 +1228,13 @@ void ClientSocketPoolBaseHelper::TryToCloseSocketsInLayeredPools() {
ClientSocketPoolBaseHelper::Group::Group() ClientSocketPoolBaseHelper::Group::Group()
: never_assigned_job_count_(0), : never_assigned_job_count_(0),
pending_requests_(NUM_PRIORITIES), unbound_requests_(NUM_PRIORITIES),
active_socket_count_(0) {} active_socket_count_(0) {}
ClientSocketPoolBaseHelper::Group::~Group() { ClientSocketPoolBaseHelper::Group::~Group() {
DCHECK_EQ(0u, never_assigned_job_count()); DCHECK_EQ(0u, never_assigned_job_count());
DCHECK_EQ(0u, unassigned_job_count()); DCHECK_EQ(0u, unassigned_job_count());
DCHECK(pending_requests_.empty()); DCHECK(unbound_requests_.empty());
DCHECK(jobs_.empty()); DCHECK(jobs_.empty());
DCHECK(bound_requests_.empty()); DCHECK(bound_requests_.empty());
} }
...@@ -1279,7 +1279,7 @@ void ClientSocketPoolBaseHelper::Group::AddJob(std::unique_ptr<ConnectJob> job, ...@@ -1279,7 +1279,7 @@ void ClientSocketPoolBaseHelper::Group::AddJob(std::unique_ptr<ConnectJob> job,
SanityCheck(); SanityCheck();
} }
std::unique_ptr<ConnectJob> ClientSocketPoolBaseHelper::Group::RemoveJob( std::unique_ptr<ConnectJob> ClientSocketPoolBaseHelper::Group::RemoveUnboundJob(
ConnectJob* job) { ConnectJob* job) {
SanityCheck(); SanityCheck();
...@@ -1299,7 +1299,7 @@ std::unique_ptr<ConnectJob> ClientSocketPoolBaseHelper::Group::RemoveJob( ...@@ -1299,7 +1299,7 @@ std::unique_ptr<ConnectJob> ClientSocketPoolBaseHelper::Group::RemoveJob(
// try to replace it with another job if possible (either by taking an // try to replace it with another job if possible (either by taking an
// unassigned job or stealing from another request, if any requests after it // unassigned job or stealing from another request, if any requests after it
// have a job). // have a job).
RequestQueue::Pointer request_with_job = FindRequestWithJob(job); RequestQueue::Pointer request_with_job = FindUnboundRequestWithJob(job);
DCHECK(!request_with_job.is_null()); DCHECK(!request_with_job.is_null());
request_with_job.value()->ReleaseJob(); request_with_job.value()->ReleaseJob();
TryToAssignJobToRequest(request_with_job); TryToAssignJobToRequest(request_with_job);
...@@ -1355,12 +1355,12 @@ void ClientSocketPoolBaseHelper::Group::OnBackupJobTimerFired( ...@@ -1355,12 +1355,12 @@ void ClientSocketPoolBaseHelper::Group::OnBackupJobTimerFired(
return; return;
} }
if (pending_requests_.empty()) if (unbound_requests_.empty())
return; return;
std::unique_ptr<ConnectJob> backup_job = std::unique_ptr<ConnectJob> backup_job =
pool->connect_job_factory_->NewConnectJob( pool->connect_job_factory_->NewConnectJob(
group_name, *pending_requests_.FirstMax().value(), pool); group_name, *unbound_requests_.FirstMax().value(), pool);
backup_job->net_log().AddEvent(NetLogEventType::BACKUP_CONNECT_JOB_CREATED); backup_job->net_log().AddEvent(NetLogEventType::BACKUP_CONNECT_JOB_CREATED);
int rv = backup_job->Connect(); int rv = backup_job->Connect();
pool->connecting_socket_count_++; pool->connecting_socket_count_++;
...@@ -1377,13 +1377,13 @@ void ClientSocketPoolBaseHelper::Group::SanityCheck() const { ...@@ -1377,13 +1377,13 @@ void ClientSocketPoolBaseHelper::Group::SanityCheck() const {
// Check that |unassigned_jobs_| is empty iff there are at least as many // Check that |unassigned_jobs_| is empty iff there are at least as many
// requests as jobs. // requests as jobs.
DCHECK_EQ(unassigned_jobs_.empty(), jobs_.size() <= pending_requests_.size()); DCHECK_EQ(unassigned_jobs_.empty(), jobs_.size() <= unbound_requests_.size());
size_t num_assigned_jobs = jobs_.size() - unassigned_jobs_.size(); size_t num_assigned_jobs = jobs_.size() - unassigned_jobs_.size();
RequestQueue::Pointer pointer = pending_requests_.FirstMax(); RequestQueue::Pointer pointer = unbound_requests_.FirstMax();
for (size_t i = 0; i < pending_requests_.size(); for (size_t i = 0; i < unbound_requests_.size();
++i, pointer = pending_requests_.GetNextTowardsLastMin(pointer)) { ++i, pointer = unbound_requests_.GetNextTowardsLastMin(pointer)) {
DCHECK(!pointer.is_null()); DCHECK(!pointer.is_null());
DCHECK(pointer.value()); DCHECK(pointer.value());
// Check that the first |num_assigned_jobs| requests have valid job // Check that the first |num_assigned_jobs| requests have valid job
...@@ -1402,9 +1402,9 @@ void ClientSocketPoolBaseHelper::Group::SanityCheck() const { ...@@ -1402,9 +1402,9 @@ void ClientSocketPoolBaseHelper::Group::SanityCheck() const {
}) != jobs_.end()); }) != jobs_.end());
// The same job is not assigned to any other request with a job. // The same job is not assigned to any other request with a job.
RequestQueue::Pointer pointer2 = RequestQueue::Pointer pointer2 =
pending_requests_.GetNextTowardsLastMin(pointer); unbound_requests_.GetNextTowardsLastMin(pointer);
for (size_t j = i + 1; j < num_assigned_jobs; for (size_t j = i + 1; j < num_assigned_jobs;
++j, pointer2 = pending_requests_.GetNextTowardsLastMin(pointer2)) { ++j, pointer2 = unbound_requests_.GetNextTowardsLastMin(pointer2)) {
DCHECK(!pointer2.is_null()); DCHECK(!pointer2.is_null());
ConnectJob* job2 = pointer2.value()->job(); ConnectJob* job2 = pointer2.value()->job();
DCHECK(job2); DCHECK(job2);
...@@ -1445,14 +1445,14 @@ void ClientSocketPoolBaseHelper::Group::SanityCheck() const { ...@@ -1445,14 +1445,14 @@ void ClientSocketPoolBaseHelper::Group::SanityCheck() const {
#endif #endif
} }
void ClientSocketPoolBaseHelper::Group::RemoveAllJobs() { void ClientSocketPoolBaseHelper::Group::RemoveAllUnboundJobs() {
SanityCheck(); SanityCheck();
// Remove jobs from any requests that have them. // Remove jobs from any requests that have them.
if (!pending_requests_.empty()) { if (!unbound_requests_.empty()) {
for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); for (RequestQueue::Pointer pointer = unbound_requests_.FirstMax();
!pointer.is_null() && pointer.value()->job(); !pointer.is_null() && pointer.value()->job();
pointer = pending_requests_.GetNextTowardsLastMin(pointer)) { pointer = unbound_requests_.GetNextTowardsLastMin(pointer)) {
pointer.value()->ReleaseJob(); pointer.value()->ReleaseJob();
} }
} }
...@@ -1480,9 +1480,9 @@ bool ClientSocketPoolBaseHelper::Group::HasConnectJobForHandle( ...@@ -1480,9 +1480,9 @@ bool ClientSocketPoolBaseHelper::Group::HasConnectJobForHandle(
// Search through the unbound requests that have corresponding jobs for a // Search through the unbound requests that have corresponding jobs for a
// request with |handle|. // request with |handle|.
for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); for (RequestQueue::Pointer pointer = unbound_requests_.FirstMax();
!pointer.is_null() && pointer.value()->job(); !pointer.is_null() && pointer.value()->job();
pointer = pending_requests_.GetNextTowardsLastMin(pointer)) { pointer = unbound_requests_.GetNextTowardsLastMin(pointer)) {
if (pointer.value()->handle() == handle) if (pointer.value()->handle() == handle)
return true; return true;
} }
...@@ -1490,11 +1490,11 @@ bool ClientSocketPoolBaseHelper::Group::HasConnectJobForHandle( ...@@ -1490,11 +1490,11 @@ bool ClientSocketPoolBaseHelper::Group::HasConnectJobForHandle(
return false; return false;
} }
void ClientSocketPoolBaseHelper::Group::InsertPendingRequest( void ClientSocketPoolBaseHelper::Group::InsertUnboundRequest(
std::unique_ptr<Request> request) { std::unique_ptr<Request> request) {
SanityCheck(); SanityCheck();
// Should not have a job because it is not already in |pending_requests_| // Should not have a job because it is not already in |unbound_requests_|
DCHECK(!request->job()); DCHECK(!request->job());
// This value must be cached before we release |request|. // This value must be cached before we release |request|.
RequestPriority priority = request->priority(); RequestPriority priority = request->priority();
...@@ -1506,11 +1506,11 @@ void ClientSocketPoolBaseHelper::Group::InsertPendingRequest( ...@@ -1506,11 +1506,11 @@ void ClientSocketPoolBaseHelper::Group::InsertPendingRequest(
// MAXIMUM_PRIORITY. // MAXIMUM_PRIORITY.
DCHECK_EQ(priority, MAXIMUM_PRIORITY); DCHECK_EQ(priority, MAXIMUM_PRIORITY);
new_position = new_position =
pending_requests_.InsertAtFront(std::move(request), priority); unbound_requests_.InsertAtFront(std::move(request), priority);
} else { } else {
new_position = pending_requests_.Insert(std::move(request), priority); new_position = unbound_requests_.Insert(std::move(request), priority);
} }
DCHECK(!pending_requests_.empty()); DCHECK(!unbound_requests_.empty());
TryToAssignJobToRequest(new_position); TryToAssignJobToRequest(new_position);
...@@ -1518,48 +1518,34 @@ void ClientSocketPoolBaseHelper::Group::InsertPendingRequest( ...@@ -1518,48 +1518,34 @@ void ClientSocketPoolBaseHelper::Group::InsertPendingRequest(
} }
const ClientSocketPoolBaseHelper::Request* const ClientSocketPoolBaseHelper::Request*
ClientSocketPoolBaseHelper::Group::GetNextPendingRequest() const { ClientSocketPoolBaseHelper::Group::GetNextUnboundRequest() const {
return pending_requests_.empty() ? nullptr return unbound_requests_.empty() ? nullptr
: pending_requests_.FirstMax().value().get(); : unbound_requests_.FirstMax().value().get();
} }
std::unique_ptr<ClientSocketPoolBaseHelper::Request> std::unique_ptr<ClientSocketPoolBaseHelper::Request>
ClientSocketPoolBaseHelper::Group::PopNextPendingRequest() { ClientSocketPoolBaseHelper::Group::PopNextUnboundRequest() {
if (pending_requests_.empty()) if (unbound_requests_.empty())
return std::unique_ptr<ClientSocketPoolBaseHelper::Request>(); return std::unique_ptr<ClientSocketPoolBaseHelper::Request>();
return RemovePendingRequest(pending_requests_.FirstMax()); return RemoveUnboundRequest(unbound_requests_.FirstMax());
} }
std::unique_ptr<ClientSocketPoolBaseHelper::Request> std::unique_ptr<ClientSocketPoolBaseHelper::Request>
ClientSocketPoolBaseHelper::Group::FindAndRemovePendingRequest( ClientSocketPoolBaseHelper::Group::FindAndRemoveUnboundRequest(
ClientSocketHandle* handle) { ClientSocketHandle* handle) {
for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); for (RequestQueue::Pointer pointer = unbound_requests_.FirstMax();
!pointer.is_null(); !pointer.is_null();
pointer = pending_requests_.GetNextTowardsLastMin(pointer)) { pointer = unbound_requests_.GetNextTowardsLastMin(pointer)) {
if (pointer.value()->handle() == handle) { if (pointer.value()->handle() == handle) {
DCHECK_EQ(static_cast<RequestPriority>(pointer.priority()), DCHECK_EQ(static_cast<RequestPriority>(pointer.priority()),
pointer.value()->priority()); pointer.value()->priority());
std::unique_ptr<Request> request = RemovePendingRequest(pointer); std::unique_ptr<Request> request = RemoveUnboundRequest(pointer);
return request; return request;
} }
} }
return std::unique_ptr<ClientSocketPoolBaseHelper::Request>(); return std::unique_ptr<ClientSocketPoolBaseHelper::Request>();
} }
std::unique_ptr<ClientSocketPoolBaseHelper::Request>
ClientSocketPoolBaseHelper::Group::FindAndRemoveBoundRequest(
ClientSocketHandle* client_socket_handle) {
for (auto bound_pair = bound_requests_.begin();
bound_pair != bound_requests_.end(); ++bound_pair) {
if (bound_pair->request->handle() != client_socket_handle)
continue;
std::unique_ptr<Request> request = std::move(bound_pair->request);
bound_requests_.erase(bound_pair);
return request;
}
return nullptr;
}
void ClientSocketPoolBaseHelper::Group::SetPendingErrorForAllBoundRequests( void ClientSocketPoolBaseHelper::Group::SetPendingErrorForAllBoundRequests(
int pending_error) { int pending_error) {
for (auto bound_pair = bound_requests_.begin(); for (auto bound_pair = bound_requests_.begin();
...@@ -1580,16 +1566,16 @@ ClientSocketPoolBaseHelper::Group::BindRequestToConnectJob( ...@@ -1580,16 +1566,16 @@ ClientSocketPoolBaseHelper::Group::BindRequestToConnectJob(
} }
// If not, try to bind it to a Request. // If not, try to bind it to a Request.
const Request* request = GetNextPendingRequest(); const Request* request = GetNextUnboundRequest();
// If there are no pending requests, or the highest priority request has no // If there are no pending requests, or the highest priority request has no
// callback to handle auth challenges, return nullptr. // callback to handle auth challenges, return nullptr.
if (!request || request->proxy_auth_callback().is_null()) if (!request || request->proxy_auth_callback().is_null())
return nullptr; return nullptr;
// Otherwise, bind the ConnectJob to the Request. // Otherwise, bind the ConnectJob to the Request.
std::unique_ptr<Request> owned_request = PopNextPendingRequest(); std::unique_ptr<Request> owned_request = PopNextUnboundRequest();
DCHECK_EQ(owned_request.get(), request); DCHECK_EQ(owned_request.get(), request);
std::unique_ptr<ConnectJob> owned_connect_job = RemoveJob(connect_job); std::unique_ptr<ConnectJob> owned_connect_job = RemoveUnboundJob(connect_job);
LogBoundConnectJobToRequest(owned_connect_job->net_log().source(), *request); LogBoundConnectJobToRequest(owned_connect_job->net_log().source(), *request);
bound_requests_.emplace_back( bound_requests_.emplace_back(
BoundRequest(std::move(owned_connect_job), std::move(owned_request))); BoundRequest(std::move(owned_connect_job), std::move(owned_request)));
...@@ -1612,16 +1598,30 @@ ClientSocketPoolBaseHelper::Group::FindAndRemoveBoundRequestForConnectJob( ...@@ -1612,16 +1598,30 @@ ClientSocketPoolBaseHelper::Group::FindAndRemoveBoundRequestForConnectJob(
return nullptr; return nullptr;
} }
std::unique_ptr<ClientSocketPoolBaseHelper::Request>
ClientSocketPoolBaseHelper::Group::FindAndRemoveBoundRequest(
ClientSocketHandle* client_socket_handle) {
for (auto bound_pair = bound_requests_.begin();
bound_pair != bound_requests_.end(); ++bound_pair) {
if (bound_pair->request->handle() != client_socket_handle)
continue;
std::unique_ptr<Request> request = std::move(bound_pair->request);
bound_requests_.erase(bound_pair);
return request;
}
return nullptr;
}
void ClientSocketPoolBaseHelper::Group::SetPriority(ClientSocketHandle* handle, void ClientSocketPoolBaseHelper::Group::SetPriority(ClientSocketHandle* handle,
RequestPriority priority) { RequestPriority priority) {
for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); for (RequestQueue::Pointer pointer = unbound_requests_.FirstMax();
!pointer.is_null(); !pointer.is_null();
pointer = pending_requests_.GetNextTowardsLastMin(pointer)) { pointer = unbound_requests_.GetNextTowardsLastMin(pointer)) {
if (pointer.value()->handle() == handle) { if (pointer.value()->handle() == handle) {
if (pointer.value()->priority() == priority) if (pointer.value()->priority() == priority)
return; return;
std::unique_ptr<Request> request = RemovePendingRequest(pointer); std::unique_ptr<Request> request = RemoveUnboundRequest(pointer);
// Requests that ignore limits much be created and remain at the highest // Requests that ignore limits much be created and remain at the highest
// priority, and should not be reprioritized. // priority, and should not be reprioritized.
...@@ -1629,7 +1629,7 @@ void ClientSocketPoolBaseHelper::Group::SetPriority(ClientSocketHandle* handle, ...@@ -1629,7 +1629,7 @@ void ClientSocketPoolBaseHelper::Group::SetPriority(ClientSocketHandle* handle,
ClientSocketPool::RespectLimits::ENABLED); ClientSocketPool::RespectLimits::ENABLED);
request->set_priority(priority); request->set_priority(priority);
InsertPendingRequest(std::move(request)); InsertUnboundRequest(std::move(request));
return; return;
} }
} }
...@@ -1646,11 +1646,11 @@ bool ClientSocketPoolBaseHelper::Group::RequestWithHandleHasJobForTesting( ...@@ -1646,11 +1646,11 @@ bool ClientSocketPoolBaseHelper::Group::RequestWithHandleHasJobForTesting(
// There's no corresponding ConnectJob. Verify that the handle is at least // There's no corresponding ConnectJob. Verify that the handle is at least
// owned by a request. // owned by a request.
RequestQueue::Pointer pointer = pending_requests_.FirstMax(); RequestQueue::Pointer pointer = unbound_requests_.FirstMax();
for (size_t i = 0; i < pending_requests_.size(); ++i) { for (size_t i = 0; i < unbound_requests_.size(); ++i) {
if (pointer.value()->handle() == handle) if (pointer.value()->handle() == handle)
return false; return false;
pointer = pending_requests_.GetNextTowardsLastMin(pointer); pointer = unbound_requests_.GetNextTowardsLastMin(pointer);
} }
NOTREACHED(); NOTREACHED();
return false; return false;
...@@ -1676,20 +1676,19 @@ ClientSocketPoolBaseHelper::Group::BoundRequest::operator=( ...@@ -1676,20 +1676,19 @@ ClientSocketPoolBaseHelper::Group::BoundRequest::operator=(
ClientSocketPoolBaseHelper::Group::BoundRequest::~BoundRequest() = default; ClientSocketPoolBaseHelper::Group::BoundRequest::~BoundRequest() = default;
std::unique_ptr<ClientSocketPoolBaseHelper::Request> std::unique_ptr<ClientSocketPoolBaseHelper::Request>
ClientSocketPoolBaseHelper::Group::RemovePendingRequest( ClientSocketPoolBaseHelper::Group::RemoveUnboundRequest(
const RequestQueue::Pointer& pointer) { const RequestQueue::Pointer& pointer) {
SanityCheck(); SanityCheck();
// TODO(eroman): Temporary for debugging http://crbug.com/467797. // TODO(eroman): Temporary for debugging http://crbug.com/467797.
CHECK(!pointer.is_null()); CHECK(!pointer.is_null());
std::unique_ptr<Request> request = pending_requests_.Erase(pointer); std::unique_ptr<Request> request = unbound_requests_.Erase(pointer);
if (request->job()) { if (request->job()) {
TryToAssignUnassignedJob(request->ReleaseJob()); TryToAssignUnassignedJob(request->ReleaseJob());
} }
// If there are no more requests, kill the backup timer. // If there are no more unbound requests, kill the backup timer.
if (pending_requests_.empty()) { if (unbound_requests_.empty())
backup_job_timer_.Stop(); backup_job_timer_.Stop();
}
request->CrashIfInvalid(); request->CrashIfInvalid();
SanityCheck(); SanityCheck();
...@@ -1697,13 +1696,13 @@ ClientSocketPoolBaseHelper::Group::RemovePendingRequest( ...@@ -1697,13 +1696,13 @@ ClientSocketPoolBaseHelper::Group::RemovePendingRequest(
} }
ClientSocketPoolBaseHelper::RequestQueue::Pointer ClientSocketPoolBaseHelper::RequestQueue::Pointer
ClientSocketPoolBaseHelper::Group::FindRequestWithJob( ClientSocketPoolBaseHelper::Group::FindUnboundRequestWithJob(
const ConnectJob* job) const { const ConnectJob* job) const {
SanityCheck(); SanityCheck();
for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); for (RequestQueue::Pointer pointer = unbound_requests_.FirstMax();
!pointer.is_null() && pointer.value()->job(); !pointer.is_null() && pointer.value()->job();
pointer = pending_requests_.GetNextTowardsLastMin(pointer)) { pointer = unbound_requests_.GetNextTowardsLastMin(pointer)) {
if (pointer.value()->job() == job) if (pointer.value()->job() == job)
return pointer; return pointer;
} }
...@@ -1715,10 +1714,10 @@ ClientSocketPoolBaseHelper::Group::FindRequestWithJob( ...@@ -1715,10 +1714,10 @@ ClientSocketPoolBaseHelper::Group::FindRequestWithJob(
ClientSocketPoolBaseHelper::RequestQueue::Pointer ClientSocketPoolBaseHelper::RequestQueue::Pointer
ClientSocketPoolBaseHelper::Group::GetFirstRequestWithoutJob() const { ClientSocketPoolBaseHelper::Group::GetFirstRequestWithoutJob() const {
RequestQueue::Pointer pointer = pending_requests_.FirstMax(); RequestQueue::Pointer pointer = unbound_requests_.FirstMax();
size_t i = 0; size_t i = 0;
for (; !pointer.is_null() && pointer.value()->job(); for (; !pointer.is_null() && pointer.value()->job();
pointer = pending_requests_.GetNextTowardsLastMin(pointer)) { pointer = unbound_requests_.GetNextTowardsLastMin(pointer)) {
++i; ++i;
} }
DCHECK_EQ(i, jobs_.size() - unassigned_jobs_.size()); DCHECK_EQ(i, jobs_.size() - unassigned_jobs_.size());
...@@ -1748,16 +1747,16 @@ void ClientSocketPoolBaseHelper::Group::TryToAssignJobToRequest( ...@@ -1748,16 +1747,16 @@ void ClientSocketPoolBaseHelper::Group::TryToAssignJobToRequest(
// If the next request in the queue does not have a job, then there are no // If the next request in the queue does not have a job, then there are no
// requests with a job after |request_pointer| from which we can steal. // requests with a job after |request_pointer| from which we can steal.
RequestQueue::Pointer next_request = RequestQueue::Pointer next_request =
pending_requests_.GetNextTowardsLastMin(request_pointer); unbound_requests_.GetNextTowardsLastMin(request_pointer);
if (next_request.is_null() || !next_request.value()->job()) if (next_request.is_null() || !next_request.value()->job())
return; return;
// Walk down the queue to find the last request with a job. // Walk down the queue to find the last request with a job.
RequestQueue::Pointer cur = next_request; RequestQueue::Pointer cur = next_request;
RequestQueue::Pointer next = pending_requests_.GetNextTowardsLastMin(cur); RequestQueue::Pointer next = unbound_requests_.GetNextTowardsLastMin(cur);
while (!next.is_null() && next.value()->job()) { while (!next.is_null() && next.value()->job()) {
cur = next; cur = next;
next = pending_requests_.GetNextTowardsLastMin(next); next = unbound_requests_.GetNextTowardsLastMin(next);
} }
// Steal the job from the last request with a job. // Steal the job from the last request with a job.
TransferJobBetweenRequests(cur.value().get(), request_pointer.value().get()); TransferJobBetweenRequests(cur.value().get(), request_pointer.value().get());
......
...@@ -237,6 +237,7 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper ...@@ -237,6 +237,7 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper
ClientSocketPool::kMaxConnectRetryIntervalMs); ClientSocketPool::kMaxConnectRetryIntervalMs);
} }
// TODO(mmenke): de-inline these.
size_t NumNeverAssignedConnectJobsInGroup( size_t NumNeverAssignedConnectJobsInGroup(
const std::string& group_name) const { const std::string& group_name) const {
return group_map_.find(group_name)->second->never_assigned_job_count(); return group_map_.find(group_name)->second->never_assigned_job_count();
...@@ -323,8 +324,9 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper ...@@ -323,8 +324,9 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper
using RequestQueue = PriorityQueue<std::unique_ptr<Request>>; using RequestQueue = PriorityQueue<std::unique_ptr<Request>>;
// A Group is allocated per group_name when there are idle sockets or pending // A Group is allocated per group_name when there are idle sockets, unbound
// requests. Otherwise, the Group object is removed from the map. // request, or bound requests. Otherwise, the Group object is removed from the
// map.
// //
// A request is "bound" to a ConnectJob when an unbound ConnectJob encounters // A request is "bound" to a ConnectJob when an unbound ConnectJob encounters
// a proxy HTTP auth challenge, and the auth challenge is presented to that // a proxy HTTP auth challenge, and the auth challenge is presented to that
...@@ -355,7 +357,7 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper ...@@ -355,7 +357,7 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper
bool IsEmpty() const { bool IsEmpty() const {
return active_socket_count_ == 0 && idle_sockets_.empty() && return active_socket_count_ == 0 && idle_sockets_.empty() &&
jobs_.empty() && pending_requests_.empty() && jobs_.empty() && unbound_requests_.empty() &&
bound_requests_.empty(); bound_requests_.empty();
} }
...@@ -373,17 +375,17 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper ...@@ -373,17 +375,17 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper
// it were given one. // it were given one.
bool CanUseAdditionalSocketSlot(int max_sockets_per_group) const { bool CanUseAdditionalSocketSlot(int max_sockets_per_group) const {
return HasAvailableSocketSlot(max_sockets_per_group) && return HasAvailableSocketSlot(max_sockets_per_group) &&
pending_requests_.size() > jobs_.size(); unbound_requests_.size() > jobs_.size();
} }
// Returns the priority of the top of the pending request queue // Returns the priority of the top of the unbound request queue
// (which may be less than the maximum priority over the entire // (which may be less than the maximum priority over the entire
// queue, due to how we prioritize requests with |respect_limits| // queue, due to how we prioritize requests with |respect_limits|
// DISABLED over others). // DISABLED over others).
RequestPriority TopPendingPriority() const { RequestPriority TopPendingPriority() const {
// NOTE: FirstMax().value()->priority() is not the same as // NOTE: FirstMax().value()->priority() is not the same as
// FirstMax().priority()! // FirstMax().priority()!
return pending_requests_.FirstMax().value()->priority(); return unbound_requests_.FirstMax().value()->priority();
} }
// Set a timer to create a backup job if it takes too long to // Set a timer to create a backup job if it takes too long to
...@@ -401,16 +403,12 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper ...@@ -401,16 +403,12 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper
void AddJob(std::unique_ptr<ConnectJob> job, bool is_preconnect); void AddJob(std::unique_ptr<ConnectJob> job, bool is_preconnect);
// Remove |job| from this group, which must already own |job|. Returns the // Remove |job| from this group, which must already own |job|. Returns the
// removed ConnectJob. // removed ConnectJob.
std::unique_ptr<ConnectJob> RemoveJob(ConnectJob* job); std::unique_ptr<ConnectJob> RemoveUnboundJob(ConnectJob* job);
void RemoveAllJobs(); void RemoveAllUnboundJobs();
bool has_pending_requests() const { bool has_unbound_requests() const { return !unbound_requests_.empty(); }
return !pending_requests_.empty();
}
size_t pending_request_count() const { size_t unbound_request_count() const { return unbound_requests_.size(); }
return pending_requests_.size();
}
size_t ConnectJobCount() const; size_t ConnectJobCount() const;
...@@ -420,19 +418,19 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper ...@@ -420,19 +418,19 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper
// Inserts the request into the queue based on priority // Inserts the request into the queue based on priority
// order. Older requests are prioritized over requests of equal // order. Older requests are prioritized over requests of equal
// priority. // priority.
void InsertPendingRequest(std::unique_ptr<Request> request); void InsertUnboundRequest(std::unique_ptr<Request> request);
// Gets (but does not remove) the next pending request. Returns // Gets (but does not remove) the next unbound request. Returns
// NULL if there are no pending requests. // NULL if there are no unbound requests.
const Request* GetNextPendingRequest() const; const Request* GetNextUnboundRequest() const;
// Gets and removes the next pending request. Returns NULL if // Gets and removes the next unbound request. Returns NULL if
// there are no pending requests. // there are no unbound requests.
std::unique_ptr<Request> PopNextPendingRequest(); std::unique_ptr<Request> PopNextUnboundRequest();
// Finds the pending request for |handle| and removes it. Returns // Finds the unbound request for |handle| and removes it. Returns
// the removed pending request, or NULL if there was none. // the removed unbound request, or NULL if there was none.
std::unique_ptr<Request> FindAndRemovePendingRequest( std::unique_ptr<Request> FindAndRemoveUnboundRequest(
ClientSocketHandle* handle); ClientSocketHandle* handle);
// Sets a pending error for all bound requests. Bound requests may be in the // Sets a pending error for all bound requests. Bound requests may be in the
...@@ -468,7 +466,7 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper ...@@ -468,7 +466,7 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper
void IncrementActiveSocketCount() { active_socket_count_++; } void IncrementActiveSocketCount() { active_socket_count_++; }
void DecrementActiveSocketCount() { active_socket_count_--; } void DecrementActiveSocketCount() { active_socket_count_--; }
// Whether the request in |pending_requests_| with a given handle has a job. // Whether the request in |unbound_requests_| with a given handle has a job.
bool RequestWithHandleHasJobForTesting( bool RequestWithHandleHasJobForTesting(
const ClientSocketHandle* handle) const; const ClientSocketHandle* handle) const;
...@@ -501,17 +499,18 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper ...@@ -501,17 +499,18 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper
int pending_error; int pending_error;
}; };
// Returns the iterator's pending request after removing it from // Returns the iterator's unbound request after removing it from
// the queue. Expects the Group to pass SanityCheck() when called. // the queue. Expects the Group to pass SanityCheck() when called.
std::unique_ptr<Request> RemovePendingRequest( std::unique_ptr<Request> RemoveUnboundRequest(
const RequestQueue::Pointer& pointer); const RequestQueue::Pointer& pointer);
// Finds the Request which is associated with the given ConnectJob. // Finds the Request which is associated with the given ConnectJob.
// Returns nullptr if none is found. Expects the Group to pass SanityCheck() // Returns nullptr if none is found. Expects the Group to pass SanityCheck()
// when called. // when called.
RequestQueue::Pointer FindRequestWithJob(const ConnectJob* job) const; RequestQueue::Pointer FindUnboundRequestWithJob(
const ConnectJob* job) const;
// Finds the Request in |pending_requests_| which is the first request // Finds the Request in |unbound_requests_| which is the first request
// without a job. Returns a null pointer if all requests have jobs. Does not // without a job. Returns a null pointer if all requests have jobs. Does not
// expect the Group to pass SanityCheck() when called, but does expect all // expect the Group to pass SanityCheck() when called, but does expect all
// jobs to either be assigned to a request or in |unassigned_jobs_|. Expects // jobs to either be assigned to a request or in |unassigned_jobs_|. Expects
...@@ -533,7 +532,7 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper ...@@ -533,7 +532,7 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper
// expect that: // expect that:
// - the request associated with |request_pointer| must not have // - the request associated with |request_pointer| must not have
// an assigned ConnectJob, // an assigned ConnectJob,
// - the first min( jobs_.size(), pending_requests_.size() - 1 ) Requests // - the first min( jobs_.size(), unbound_requests_.size() - 1 ) Requests
// other than the given request must have ConnectJobs, i.e. the group // other than the given request must have ConnectJobs, i.e. the group
// must have passed SanityCheck() before the passed in Request was either // must have passed SanityCheck() before the passed in Request was either
// added or had its job unassigned. // added or had its job unassigned.
...@@ -573,16 +572,16 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper ...@@ -573,16 +572,16 @@ class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper
JobList jobs_; // For bookkeeping purposes, there is a copy of the raw JobList jobs_; // For bookkeeping purposes, there is a copy of the raw
// pointer of each element of |jobs_| stored either in // pointer of each element of |jobs_| stored either in
// |unassigned_jobs_|, or as the associated |job_| of an // |unassigned_jobs_|, or as the associated |job_| of an
// element of |pending_requests_|. // element of |unbound_requests_|.
std::list<ConnectJob*> unassigned_jobs_; std::list<ConnectJob*> unassigned_jobs_;
RequestQueue pending_requests_; RequestQueue unbound_requests_;
int active_socket_count_; // number of active sockets used by clients int active_socket_count_; // number of active sockets used by clients
// A timer for when to start the backup job. // A timer for when to start the backup job.
base::OneShotTimer backup_job_timer_; base::OneShotTimer backup_job_timer_;
// List of Requests bound to ConnectJobs currently undergoing proxy auth. // List of Requests bound to ConnectJobs currently undergoing proxy auth.
// The Requests and ConnectJobs in this list do not appear in // The Requests and ConnectJobs in this list do not appear in
// |pending_requests_| or |jobs_|. // |unbound_requests_| or |jobs_|.
std::vector<BoundRequest> bound_requests_; std::vector<BoundRequest> bound_requests_;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment