| 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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 it != group_map_.end(); ++it) { | 233 it != group_map_.end(); ++it) { |
| 234 if (it->second->CanUseAdditionalSocketSlot(max_sockets_per_group_)) | 234 if (it->second->CanUseAdditionalSocketSlot(max_sockets_per_group_)) |
| 235 return true; | 235 return true; |
| 236 } | 236 } |
| 237 return false; | 237 return false; |
| 238 } | 238 } |
| 239 | 239 |
| 240 void ClientSocketPoolBaseHelper::AddLowerLayeredPool( | 240 void ClientSocketPoolBaseHelper::AddLowerLayeredPool( |
| 241 LowerLayeredPool* lower_pool) { | 241 LowerLayeredPool* lower_pool) { |
| 242 DCHECK(pool_); | 242 DCHECK(pool_); |
| 243 CHECK(!ContainsKey(lower_pools_, lower_pool)); | 243 CHECK(!base::ContainsKey(lower_pools_, lower_pool)); |
| 244 lower_pools_.insert(lower_pool); | 244 lower_pools_.insert(lower_pool); |
| 245 lower_pool->AddHigherLayeredPool(pool_); | 245 lower_pool->AddHigherLayeredPool(pool_); |
| 246 } | 246 } |
| 247 | 247 |
| 248 void ClientSocketPoolBaseHelper::AddHigherLayeredPool( | 248 void ClientSocketPoolBaseHelper::AddHigherLayeredPool( |
| 249 HigherLayeredPool* higher_pool) { | 249 HigherLayeredPool* higher_pool) { |
| 250 CHECK(higher_pool); | 250 CHECK(higher_pool); |
| 251 CHECK(!ContainsKey(higher_pools_, higher_pool)); | 251 CHECK(!base::ContainsKey(higher_pools_, higher_pool)); |
| 252 higher_pools_.insert(higher_pool); | 252 higher_pools_.insert(higher_pool); |
| 253 } | 253 } |
| 254 | 254 |
| 255 void ClientSocketPoolBaseHelper::RemoveHigherLayeredPool( | 255 void ClientSocketPoolBaseHelper::RemoveHigherLayeredPool( |
| 256 HigherLayeredPool* higher_pool) { | 256 HigherLayeredPool* higher_pool) { |
| 257 CHECK(higher_pool); | 257 CHECK(higher_pool); |
| 258 CHECK(ContainsKey(higher_pools_, higher_pool)); | 258 CHECK(base::ContainsKey(higher_pools_, higher_pool)); |
| 259 higher_pools_.erase(higher_pool); | 259 higher_pools_.erase(higher_pool); |
| 260 } | 260 } |
| 261 | 261 |
| 262 int ClientSocketPoolBaseHelper::RequestSocket( | 262 int ClientSocketPoolBaseHelper::RequestSocket( |
| 263 const std::string& group_name, | 263 const std::string& group_name, |
| 264 std::unique_ptr<const Request> request) { | 264 std::unique_ptr<const Request> request) { |
| 265 CHECK(!request->callback().is_null()); | 265 CHECK(!request->callback().is_null()); |
| 266 CHECK(request->handle()); | 266 CHECK(request->handle()); |
| 267 | 267 |
| 268 // Cleanup any timed-out idle sockets. | 268 // Cleanup any timed-out idle sockets. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 // RequestSocketsInternal() may delete the group. | 315 // RequestSocketsInternal() may delete the group. |
| 316 bool deleted_group = false; | 316 bool deleted_group = false; |
| 317 | 317 |
| 318 int rv = OK; | 318 int rv = OK; |
| 319 for (int num_iterations_left = num_sockets; | 319 for (int num_iterations_left = num_sockets; |
| 320 group->NumActiveSocketSlots() < num_sockets && | 320 group->NumActiveSocketSlots() < num_sockets && |
| 321 num_iterations_left > 0 ; num_iterations_left--) { | 321 num_iterations_left > 0 ; num_iterations_left--) { |
| 322 rv = RequestSocketInternal(group_name, request); | 322 rv = RequestSocketInternal(group_name, request); |
| 323 if (rv < 0 && rv != ERR_IO_PENDING) { | 323 if (rv < 0 && rv != ERR_IO_PENDING) { |
| 324 // We're encountering a synchronous error. Give up. | 324 // We're encountering a synchronous error. Give up. |
| 325 if (!ContainsKey(group_map_, group_name)) | 325 if (!base::ContainsKey(group_map_, group_name)) |
| 326 deleted_group = true; | 326 deleted_group = true; |
| 327 break; | 327 break; |
| 328 } | 328 } |
| 329 if (!ContainsKey(group_map_, group_name)) { | 329 if (!base::ContainsKey(group_map_, group_name)) { |
| 330 // Unexpected. The group should only be getting deleted on synchronous | 330 // Unexpected. The group should only be getting deleted on synchronous |
| 331 // error. | 331 // error. |
| 332 NOTREACHED(); | 332 NOTREACHED(); |
| 333 deleted_group = true; | 333 deleted_group = true; |
| 334 break; | 334 break; |
| 335 } | 335 } |
| 336 } | 336 } |
| 337 | 337 |
| 338 if (!deleted_group && group->IsEmpty()) | 338 if (!deleted_group && group->IsEmpty()) |
| 339 RemoveGroup(group_name); | 339 RemoveGroup(group_name); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 pending_callback_map_.erase(callback_it); | 515 pending_callback_map_.erase(callback_it); |
| 516 std::unique_ptr<StreamSocket> socket = handle->PassSocket(); | 516 std::unique_ptr<StreamSocket> socket = handle->PassSocket(); |
| 517 if (socket) { | 517 if (socket) { |
| 518 if (result != OK) | 518 if (result != OK) |
| 519 socket->Disconnect(); | 519 socket->Disconnect(); |
| 520 ReleaseSocket(handle->group_name(), std::move(socket), handle->id()); | 520 ReleaseSocket(handle->group_name(), std::move(socket), handle->id()); |
| 521 } | 521 } |
| 522 return; | 522 return; |
| 523 } | 523 } |
| 524 | 524 |
| 525 CHECK(ContainsKey(group_map_, group_name)); | 525 CHECK(base::ContainsKey(group_map_, group_name)); |
| 526 | 526 |
| 527 Group* group = GetOrCreateGroup(group_name); | 527 Group* group = GetOrCreateGroup(group_name); |
| 528 | 528 |
| 529 // Search pending_requests for matching handle. | 529 // Search pending_requests for matching handle. |
| 530 std::unique_ptr<const Request> request = | 530 std::unique_ptr<const Request> request = |
| 531 group->FindAndRemovePendingRequest(handle); | 531 group->FindAndRemovePendingRequest(handle); |
| 532 if (request) { | 532 if (request) { |
| 533 request->net_log().AddEvent(NetLog::TYPE_CANCELLED); | 533 request->net_log().AddEvent(NetLog::TYPE_CANCELLED); |
| 534 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); | 534 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); |
| 535 | 535 |
| 536 // We let the job run, unless we're at the socket limit and there is | 536 // We let the job run, unless we're at the socket limit and there is |
| 537 // not another request waiting on the job. | 537 // not another request waiting on the job. |
| 538 if (group->jobs().size() > group->pending_request_count() && | 538 if (group->jobs().size() > group->pending_request_count() && |
| 539 ReachedMaxSocketsLimit()) { | 539 ReachedMaxSocketsLimit()) { |
| 540 RemoveConnectJob(*group->jobs().begin(), group); | 540 RemoveConnectJob(*group->jobs().begin(), group); |
| 541 CheckForStalledSocketGroups(); | 541 CheckForStalledSocketGroups(); |
| 542 } | 542 } |
| 543 } | 543 } |
| 544 } | 544 } |
| 545 | 545 |
| 546 bool ClientSocketPoolBaseHelper::HasGroup(const std::string& group_name) const { | 546 bool ClientSocketPoolBaseHelper::HasGroup(const std::string& group_name) const { |
| 547 return ContainsKey(group_map_, group_name); | 547 return base::ContainsKey(group_map_, group_name); |
| 548 } | 548 } |
| 549 | 549 |
| 550 void ClientSocketPoolBaseHelper::CloseIdleSockets() { | 550 void ClientSocketPoolBaseHelper::CloseIdleSockets() { |
| 551 CleanupIdleSockets(true); | 551 CleanupIdleSockets(true); |
| 552 DCHECK_EQ(0, idle_socket_count_); | 552 DCHECK_EQ(0, idle_socket_count_); |
| 553 } | 553 } |
| 554 | 554 |
| 555 int ClientSocketPoolBaseHelper::IdleSocketCountInGroup( | 555 int ClientSocketPoolBaseHelper::IdleSocketCountInGroup( |
| 556 const std::string& group_name) const { | 556 const std::string& group_name) const { |
| 557 GroupMap::const_iterator i = group_map_.find(group_name); | 557 GroupMap::const_iterator i = group_map_.find(group_name); |
| 558 CHECK(i != group_map_.end()); | 558 CHECK(i != group_map_.end()); |
| 559 | 559 |
| 560 return i->second->idle_sockets().size(); | 560 return i->second->idle_sockets().size(); |
| 561 } | 561 } |
| 562 | 562 |
| 563 LoadState ClientSocketPoolBaseHelper::GetLoadState( | 563 LoadState ClientSocketPoolBaseHelper::GetLoadState( |
| 564 const std::string& group_name, | 564 const std::string& group_name, |
| 565 const ClientSocketHandle* handle) const { | 565 const ClientSocketHandle* handle) const { |
| 566 if (ContainsKey(pending_callback_map_, handle)) | 566 if (base::ContainsKey(pending_callback_map_, handle)) |
| 567 return LOAD_STATE_CONNECTING; | 567 return LOAD_STATE_CONNECTING; |
| 568 | 568 |
| 569 GroupMap::const_iterator group_it = group_map_.find(group_name); | 569 GroupMap::const_iterator group_it = group_map_.find(group_name); |
| 570 if (group_it == group_map_.end()) { | 570 if (group_it == group_map_.end()) { |
| 571 // TODO(mmenke): This is actually reached in the wild, for unknown reasons. | 571 // TODO(mmenke): This is actually reached in the wild, for unknown reasons. |
| 572 // Would be great to understand why, and if it's a bug, fix it. If not, | 572 // Would be great to understand why, and if it's a bug, fix it. If not, |
| 573 // should have a test for that case. | 573 // should have a test for that case. |
| 574 NOTREACHED(); | 574 NOTREACHED(); |
| 575 return LOAD_STATE_IDLE; | 575 return LOAD_STATE_IDLE; |
| 576 } | 576 } |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 921 Group* group) { | 921 Group* group) { |
| 922 CHECK_GT(connecting_socket_count_, 0); | 922 CHECK_GT(connecting_socket_count_, 0); |
| 923 connecting_socket_count_--; | 923 connecting_socket_count_--; |
| 924 | 924 |
| 925 DCHECK(group); | 925 DCHECK(group); |
| 926 group->RemoveJob(job); | 926 group->RemoveJob(job); |
| 927 } | 927 } |
| 928 | 928 |
| 929 void ClientSocketPoolBaseHelper::OnAvailableSocketSlot( | 929 void ClientSocketPoolBaseHelper::OnAvailableSocketSlot( |
| 930 const std::string& group_name, Group* group) { | 930 const std::string& group_name, Group* group) { |
| 931 DCHECK(ContainsKey(group_map_, group_name)); | 931 DCHECK(base::ContainsKey(group_map_, group_name)); |
| 932 if (group->IsEmpty()) { | 932 if (group->IsEmpty()) { |
| 933 RemoveGroup(group_name); | 933 RemoveGroup(group_name); |
| 934 } else if (group->has_pending_requests()) { | 934 } else if (group->has_pending_requests()) { |
| 935 ProcessPendingRequest(group_name, group); | 935 ProcessPendingRequest(group_name, group); |
| 936 } | 936 } |
| 937 } | 937 } |
| 938 | 938 |
| 939 void ClientSocketPoolBaseHelper::ProcessPendingRequest( | 939 void ClientSocketPoolBaseHelper::ProcessPendingRequest( |
| 940 const std::string& group_name, Group* group) { | 940 const std::string& group_name, Group* group) { |
| 941 const Request* next_request = group->GetNextPendingRequest(); | 941 const Request* next_request = group->GetNextPendingRequest(); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1103 for (std::set<HigherLayeredPool*>::const_iterator it = higher_pools_.begin(); | 1103 for (std::set<HigherLayeredPool*>::const_iterator it = higher_pools_.begin(); |
| 1104 it != higher_pools_.end(); ++it) { | 1104 it != higher_pools_.end(); ++it) { |
| 1105 if ((*it)->CloseOneIdleConnection()) | 1105 if ((*it)->CloseOneIdleConnection()) |
| 1106 return true; | 1106 return true; |
| 1107 } | 1107 } |
| 1108 return false; | 1108 return false; |
| 1109 } | 1109 } |
| 1110 | 1110 |
| 1111 void ClientSocketPoolBaseHelper::InvokeUserCallbackLater( | 1111 void ClientSocketPoolBaseHelper::InvokeUserCallbackLater( |
| 1112 ClientSocketHandle* handle, const CompletionCallback& callback, int rv) { | 1112 ClientSocketHandle* handle, const CompletionCallback& callback, int rv) { |
| 1113 CHECK(!ContainsKey(pending_callback_map_, handle)); | 1113 CHECK(!base::ContainsKey(pending_callback_map_, handle)); |
| 1114 pending_callback_map_[handle] = CallbackResultPair(callback, rv); | 1114 pending_callback_map_[handle] = CallbackResultPair(callback, rv); |
| 1115 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1115 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 1116 FROM_HERE, base::Bind(&ClientSocketPoolBaseHelper::InvokeUserCallback, | 1116 FROM_HERE, base::Bind(&ClientSocketPoolBaseHelper::InvokeUserCallback, |
| 1117 weak_factory_.GetWeakPtr(), handle)); | 1117 weak_factory_.GetWeakPtr(), handle)); |
| 1118 } | 1118 } |
| 1119 | 1119 |
| 1120 void ClientSocketPoolBaseHelper::InvokeUserCallback( | 1120 void ClientSocketPoolBaseHelper::InvokeUserCallback( |
| 1121 ClientSocketHandle* handle) { | 1121 ClientSocketHandle* handle) { |
| 1122 PendingCallbackMap::iterator it = pending_callback_map_.find(handle); | 1122 PendingCallbackMap::iterator it = pending_callback_map_.find(handle); |
| 1123 | 1123 |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1239 } | 1239 } |
| 1240 | 1240 |
| 1241 void ClientSocketPoolBaseHelper::Group::SanityCheck() { | 1241 void ClientSocketPoolBaseHelper::Group::SanityCheck() { |
| 1242 DCHECK_LE(unassigned_job_count_, jobs_.size()); | 1242 DCHECK_LE(unassigned_job_count_, jobs_.size()); |
| 1243 } | 1243 } |
| 1244 | 1244 |
| 1245 void ClientSocketPoolBaseHelper::Group::RemoveAllJobs() { | 1245 void ClientSocketPoolBaseHelper::Group::RemoveAllJobs() { |
| 1246 SanityCheck(); | 1246 SanityCheck(); |
| 1247 | 1247 |
| 1248 // Delete active jobs. | 1248 // Delete active jobs. |
| 1249 STLDeleteElements(&jobs_); | 1249 base::STLDeleteElements(&jobs_); |
| 1250 unassigned_job_count_ = 0; | 1250 unassigned_job_count_ = 0; |
| 1251 | 1251 |
| 1252 // Stop backup job timer. | 1252 // Stop backup job timer. |
| 1253 backup_job_timer_.Stop(); | 1253 backup_job_timer_.Stop(); |
| 1254 } | 1254 } |
| 1255 | 1255 |
| 1256 const ClientSocketPoolBaseHelper::Request* | 1256 const ClientSocketPoolBaseHelper::Request* |
| 1257 ClientSocketPoolBaseHelper::Group::GetNextPendingRequest() const { | 1257 ClientSocketPoolBaseHelper::Group::GetNextPendingRequest() const { |
| 1258 return | 1258 return |
| 1259 pending_requests_.empty() ? NULL : pending_requests_.FirstMax().value(); | 1259 pending_requests_.empty() ? NULL : pending_requests_.FirstMax().value(); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1320 // If there are no more requests, kill the backup timer. | 1320 // If there are no more requests, kill the backup timer. |
| 1321 if (pending_requests_.empty()) | 1321 if (pending_requests_.empty()) |
| 1322 backup_job_timer_.Stop(); | 1322 backup_job_timer_.Stop(); |
| 1323 request->CrashIfInvalid(); | 1323 request->CrashIfInvalid(); |
| 1324 return request; | 1324 return request; |
| 1325 } | 1325 } |
| 1326 | 1326 |
| 1327 } // namespace internal | 1327 } // namespace internal |
| 1328 | 1328 |
| 1329 } // namespace net | 1329 } // namespace net |
| OLD | NEW |