Chromium Code Reviews| 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 261 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 std::unique_ptr<const Request> request) { | 282 std::unique_ptr<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 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 520 return false; | 520 return false; |
| 521 } | 521 } |
| 522 | 522 |
| 523 // static | 523 // static |
| 524 void ClientSocketPoolBaseHelper::LogBoundConnectJobToRequest( | 524 void ClientSocketPoolBaseHelper::LogBoundConnectJobToRequest( |
| 525 const NetLog::Source& connect_job_source, const Request& request) { | 525 const NetLog::Source& connect_job_source, const Request& request) { |
| 526 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, |
| 527 connect_job_source.ToEventParametersCallback()); | 527 connect_job_source.ToEventParametersCallback()); |
| 528 } | 528 } |
| 529 | 529 |
| 530 void ClientSocketPoolBaseHelper::SetPriority(const std::string& group_name, | |
| 531 ClientSocketHandle* handle, | |
| 532 RequestPriority priority) { | |
| 533 GroupMap::iterator group_it = group_map_.find(group_name); | |
| 534 if (group_it == group_map_.end()) { | |
| 535 DCHECK(ContainsKey(pending_callback_map_, handle)); | |
| 536 // The Request has already completed and been destroyed; nothing to | |
| 537 // reprioritize. | |
| 538 return; | |
| 539 } | |
| 540 | |
| 541 std::unique_ptr<Request> request = | |
| 542 group_it->second->FindAndRemovePendingRequest(handle); | |
| 543 DCHECK(request); | |
| 544 DCHECK(!request->ignore_limits()); | |
|
mmenke
2016/05/09 18:41:03
Think this is worth a comment.
Randy Smith (Not in Mondays)
2017/01/03 21:09:08
Done.
| |
| 545 request->set_priority(priority); | |
| 546 group_it->second->InsertPendingRequest(std::move(request)); | |
| 547 } | |
| 548 | |
| 530 void ClientSocketPoolBaseHelper::CancelRequest( | 549 void ClientSocketPoolBaseHelper::CancelRequest( |
| 531 const std::string& group_name, ClientSocketHandle* handle) { | 550 const std::string& group_name, ClientSocketHandle* handle) { |
| 532 PendingCallbackMap::iterator callback_it = pending_callback_map_.find(handle); | 551 PendingCallbackMap::iterator callback_it = pending_callback_map_.find(handle); |
| 533 if (callback_it != pending_callback_map_.end()) { | 552 if (callback_it != pending_callback_map_.end()) { |
| 534 int result = callback_it->second.result; | 553 int result = callback_it->second.result; |
| 535 pending_callback_map_.erase(callback_it); | 554 pending_callback_map_.erase(callback_it); |
| 536 std::unique_ptr<StreamSocket> socket = handle->PassSocket(); | 555 std::unique_ptr<StreamSocket> socket = handle->PassSocket(); |
| 537 if (socket) { | 556 if (socket) { |
| 538 if (result != OK) | 557 if (result != OK) |
| 539 socket->Disconnect(); | 558 socket->Disconnect(); |
| 540 ReleaseSocket(handle->group_name(), std::move(socket), handle->id()); | 559 ReleaseSocket(handle->group_name(), std::move(socket), handle->id()); |
| 541 } | 560 } |
| 542 return; | 561 return; |
| 543 } | 562 } |
| 544 | 563 |
| 545 CHECK(ContainsKey(group_map_, group_name)); | 564 CHECK(ContainsKey(group_map_, group_name)); |
| 546 | 565 |
| 547 Group* group = GetOrCreateGroup(group_name); | 566 Group* group = GetOrCreateGroup(group_name); |
| 548 | 567 |
| 549 // Search pending_requests for matching handle. | 568 // Search pending_requests for matching handle. |
| 550 std::unique_ptr<const Request> request = | 569 std::unique_ptr<Request> request = group->FindAndRemovePendingRequest(handle); |
| 551 group->FindAndRemovePendingRequest(handle); | |
| 552 if (request) { | 570 if (request) { |
| 553 request->net_log().AddEvent(NetLog::TYPE_CANCELLED); | 571 request->net_log().AddEvent(NetLog::TYPE_CANCELLED); |
| 554 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); | 572 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); |
| 555 | 573 |
| 556 // We let the job run, unless we're at the socket limit and there is | 574 // We let the job run, unless we're at the socket limit and there is |
| 557 // not another request waiting on the job. | 575 // not another request waiting on the job. |
| 558 if (group->jobs().size() > group->pending_request_count() && | 576 if (group->jobs().size() > group->pending_request_count() && |
| 559 ReachedMaxSocketsLimit()) { | 577 ReachedMaxSocketsLimit()) { |
| 560 RemoveConnectJob(*group->jobs().begin(), group); | 578 RemoveConnectJob(*group->jobs().begin(), group); |
| 561 CheckForStalledSocketGroups(); | 579 CheckForStalledSocketGroups(); |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 897 // accessed. | 915 // accessed. |
| 898 BoundNetLog job_log = job->net_log(); | 916 BoundNetLog job_log = job->net_log(); |
| 899 LoadTimingInfo::ConnectTiming connect_timing = job->connect_timing(); | 917 LoadTimingInfo::ConnectTiming connect_timing = job->connect_timing(); |
| 900 | 918 |
| 901 // RemoveConnectJob(job, _) must be called by all branches below; | 919 // RemoveConnectJob(job, _) must be called by all branches below; |
| 902 // otherwise, |job| will be leaked. | 920 // otherwise, |job| will be leaked. |
| 903 | 921 |
| 904 if (result == OK) { | 922 if (result == OK) { |
| 905 DCHECK(socket.get()); | 923 DCHECK(socket.get()); |
| 906 RemoveConnectJob(job, group); | 924 RemoveConnectJob(job, group); |
| 907 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); | 925 std::unique_ptr<Request> request = group->PopNextPendingRequest(); |
| 908 if (request) { | 926 if (request) { |
| 909 LogBoundConnectJobToRequest(job_log.source(), *request); | 927 LogBoundConnectJobToRequest(job_log.source(), *request); |
| 910 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, | 928 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, |
| 911 connect_timing, request->handle(), base::TimeDelta(), group, | 929 connect_timing, request->handle(), base::TimeDelta(), group, |
| 912 request->net_log()); | 930 request->net_log()); |
| 913 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); | 931 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL); |
| 914 InvokeUserCallbackLater(request->handle(), request->callback(), result); | 932 InvokeUserCallbackLater(request->handle(), request->callback(), result); |
| 915 } else { | 933 } else { |
| 916 AddIdleSocket(std::move(socket), group); | 934 AddIdleSocket(std::move(socket), group); |
| 917 OnAvailableSocketSlot(group_name, group); | 935 OnAvailableSocketSlot(group_name, group); |
| 918 CheckForStalledSocketGroups(); | 936 CheckForStalledSocketGroups(); |
| 919 } | 937 } |
| 920 } else { | 938 } else { |
| 921 // If we got a socket, it must contain error information so pass that | 939 // If we got a socket, it must contain error information so pass that |
| 922 // up so that the caller can retrieve it. | 940 // up so that the caller can retrieve it. |
| 923 bool handed_out_socket = false; | 941 bool handed_out_socket = false; |
| 924 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); | 942 std::unique_ptr<Request> request = group->PopNextPendingRequest(); |
| 925 if (request) { | 943 if (request) { |
| 926 LogBoundConnectJobToRequest(job_log.source(), *request); | 944 LogBoundConnectJobToRequest(job_log.source(), *request); |
| 927 job->GetAdditionalErrorState(request->handle()); | 945 job->GetAdditionalErrorState(request->handle()); |
| 928 RemoveConnectJob(job, group); | 946 RemoveConnectJob(job, group); |
| 929 if (socket.get()) { | 947 if (socket.get()) { |
| 930 handed_out_socket = true; | 948 handed_out_socket = true; |
| 931 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, | 949 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, |
| 932 connect_timing, request->handle(), base::TimeDelta(), | 950 connect_timing, request->handle(), base::TimeDelta(), |
| 933 group, request->net_log()); | 951 group, request->net_log()); |
| 934 } | 952 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 983 // If the group has no idle sockets, and can't make use of an additional slot, | 1001 // If the group has no idle sockets, and can't make use of an additional slot, |
| 984 // either because it's at the limit or because it's at the socket per group | 1002 // either because it's at the limit or because it's at the socket per group |
| 985 // limit, then there's nothing to do. | 1003 // limit, then there's nothing to do. |
| 986 if (group->idle_sockets().empty() && | 1004 if (group->idle_sockets().empty() && |
| 987 !group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) { | 1005 !group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) { |
| 988 return; | 1006 return; |
| 989 } | 1007 } |
| 990 | 1008 |
| 991 int rv = RequestSocketInternal(group_name, *next_request); | 1009 int rv = RequestSocketInternal(group_name, *next_request); |
| 992 if (rv != ERR_IO_PENDING) { | 1010 if (rv != ERR_IO_PENDING) { |
| 993 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); | 1011 std::unique_ptr<Request> request = group->PopNextPendingRequest(); |
| 994 DCHECK(request); | 1012 DCHECK(request); |
| 995 if (group->IsEmpty()) | 1013 if (group->IsEmpty()) |
| 996 RemoveGroup(group_name); | 1014 RemoveGroup(group_name); |
| 997 | 1015 |
| 998 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); | 1016 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); |
| 999 InvokeUserCallbackLater(request->handle(), request->callback(), rv); | 1017 InvokeUserCallbackLater(request->handle(), request->callback(), rv); |
| 1000 } | 1018 } |
| 1001 } | 1019 } |
| 1002 | 1020 |
| 1003 void ClientSocketPoolBaseHelper::HandOutSocket( | 1021 void ClientSocketPoolBaseHelper::HandOutSocket( |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1059 } | 1077 } |
| 1060 } | 1078 } |
| 1061 DCHECK_EQ(0, connecting_socket_count_); | 1079 DCHECK_EQ(0, connecting_socket_count_); |
| 1062 } | 1080 } |
| 1063 | 1081 |
| 1064 void ClientSocketPoolBaseHelper::CancelAllRequestsWithError(int error) { | 1082 void ClientSocketPoolBaseHelper::CancelAllRequestsWithError(int error) { |
| 1065 for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end();) { | 1083 for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end();) { |
| 1066 Group* group = i->second; | 1084 Group* group = i->second; |
| 1067 | 1085 |
| 1068 while (true) { | 1086 while (true) { |
| 1069 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); | 1087 std::unique_ptr<Request> request = group->PopNextPendingRequest(); |
| 1070 if (!request) | 1088 if (!request) |
| 1071 break; | 1089 break; |
| 1072 InvokeUserCallbackLater(request->handle(), request->callback(), error); | 1090 InvokeUserCallbackLater(request->handle(), request->callback(), error); |
| 1073 } | 1091 } |
| 1074 | 1092 |
| 1075 // Delete group if no longer needed. | 1093 // Delete group if no longer needed. |
| 1076 if (group->IsEmpty()) { | 1094 if (group->IsEmpty()) { |
| 1077 // RemoveGroup() will call .erase() which will invalidate the iterator, | 1095 // RemoveGroup() will call .erase() which will invalidate the iterator, |
| 1078 // but i will already have been incremented to a valid iterator before | 1096 // but i will already have been incremented to a valid iterator before |
| 1079 // RemoveGroup() is called. | 1097 // RemoveGroup() is called. |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1297 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); | 1315 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); |
| 1298 !pointer.is_null() && i < jobs_.size(); | 1316 !pointer.is_null() && i < jobs_.size(); |
| 1299 pointer = pending_requests_.GetNextTowardsLastMin(pointer), ++i) { | 1317 pointer = pending_requests_.GetNextTowardsLastMin(pointer), ++i) { |
| 1300 if (pointer.value()->handle() == handle) | 1318 if (pointer.value()->handle() == handle) |
| 1301 return true; | 1319 return true; |
| 1302 } | 1320 } |
| 1303 return false; | 1321 return false; |
| 1304 } | 1322 } |
| 1305 | 1323 |
| 1306 void ClientSocketPoolBaseHelper::Group::InsertPendingRequest( | 1324 void ClientSocketPoolBaseHelper::Group::InsertPendingRequest( |
| 1307 std::unique_ptr<const Request> request) { | 1325 std::unique_ptr<Request> request) { |
| 1308 // This value must be cached before we release |request|. | 1326 // This value must be cached before we release |request|. |
| 1309 RequestPriority priority = request->priority(); | 1327 RequestPriority priority = request->priority(); |
| 1310 if (request->respect_limits() == ClientSocketPool::RespectLimits::DISABLED) { | 1328 if (request->respect_limits() == ClientSocketPool::RespectLimits::DISABLED) { |
| 1311 // Put requests with RespectLimits::DISABLED (which should have | 1329 // Put requests with RespectLimits::DISABLED (which should have |
| 1312 // priority == MAXIMUM_PRIORITY) ahead of other requests with | 1330 // priority == MAXIMUM_PRIORITY) ahead of other requests with |
| 1313 // MAXIMUM_PRIORITY. | 1331 // MAXIMUM_PRIORITY. |
| 1314 DCHECK_EQ(priority, MAXIMUM_PRIORITY); | 1332 DCHECK_EQ(priority, MAXIMUM_PRIORITY); |
| 1315 pending_requests_.InsertAtFront(request.release(), priority); | 1333 pending_requests_.InsertAtFront(request.release(), priority); |
| 1316 } else { | 1334 } else { |
| 1317 pending_requests_.Insert(request.release(), priority); | 1335 pending_requests_.Insert(request.release(), priority); |
| 1318 } | 1336 } |
| 1319 } | 1337 } |
| 1320 | 1338 |
| 1321 std::unique_ptr<const ClientSocketPoolBaseHelper::Request> | 1339 std::unique_ptr<ClientSocketPoolBaseHelper::Request> |
| 1322 ClientSocketPoolBaseHelper::Group::PopNextPendingRequest() { | 1340 ClientSocketPoolBaseHelper::Group::PopNextPendingRequest() { |
| 1323 if (pending_requests_.empty()) | 1341 if (pending_requests_.empty()) |
| 1324 return std::unique_ptr<const ClientSocketPoolBaseHelper::Request>(); | 1342 return std::unique_ptr<ClientSocketPoolBaseHelper::Request>(); |
| 1325 return RemovePendingRequest(pending_requests_.FirstMax()); | 1343 return RemovePendingRequest(pending_requests_.FirstMax()); |
| 1326 } | 1344 } |
| 1327 | 1345 |
| 1328 std::unique_ptr<const ClientSocketPoolBaseHelper::Request> | 1346 std::unique_ptr<ClientSocketPoolBaseHelper::Request> |
| 1329 ClientSocketPoolBaseHelper::Group::FindAndRemovePendingRequest( | 1347 ClientSocketPoolBaseHelper::Group::FindAndRemovePendingRequest( |
| 1330 ClientSocketHandle* handle) { | 1348 ClientSocketHandle* handle) { |
| 1331 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); | 1349 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); |
| 1332 !pointer.is_null(); | 1350 !pointer.is_null(); |
| 1333 pointer = pending_requests_.GetNextTowardsLastMin(pointer)) { | 1351 pointer = pending_requests_.GetNextTowardsLastMin(pointer)) { |
| 1334 if (pointer.value()->handle() == handle) { | 1352 if (pointer.value()->handle() == handle) { |
| 1335 std::unique_ptr<const Request> request = RemovePendingRequest(pointer); | 1353 std::unique_ptr<Request> request = RemovePendingRequest(pointer); |
| 1336 return request; | 1354 return request; |
| 1337 } | 1355 } |
| 1338 } | 1356 } |
| 1339 return std::unique_ptr<const ClientSocketPoolBaseHelper::Request>(); | 1357 return std::unique_ptr<ClientSocketPoolBaseHelper::Request>(); |
| 1340 } | 1358 } |
| 1341 | 1359 |
| 1342 std::unique_ptr<const ClientSocketPoolBaseHelper::Request> | 1360 std::unique_ptr<ClientSocketPoolBaseHelper::Request> |
| 1343 ClientSocketPoolBaseHelper::Group::RemovePendingRequest( | 1361 ClientSocketPoolBaseHelper::Group::RemovePendingRequest( |
| 1344 const RequestQueue::Pointer& pointer) { | 1362 const RequestQueue::Pointer& pointer) { |
| 1345 // TODO(eroman): Temporary for debugging http://crbug.com/467797. | 1363 // TODO(eroman): Temporary for debugging http://crbug.com/467797. |
| 1346 CHECK(!pointer.is_null()); | 1364 CHECK(!pointer.is_null()); |
| 1347 std::unique_ptr<const Request> request(pointer.value()); | 1365 std::unique_ptr<Request> request(pointer.value()); |
| 1348 pending_requests_.Erase(pointer); | 1366 pending_requests_.Erase(pointer); |
| 1349 // If there are no more requests, kill the backup timer. | 1367 // If there are no more requests, kill the backup timer. |
| 1350 if (pending_requests_.empty()) | 1368 if (pending_requests_.empty()) |
| 1351 backup_job_timer_.Stop(); | 1369 backup_job_timer_.Stop(); |
| 1352 request->CrashIfInvalid(); | 1370 request->CrashIfInvalid(); |
| 1353 return request; | 1371 return request; |
| 1354 } | 1372 } |
| 1355 | 1373 |
| 1356 } // namespace internal | 1374 } // namespace internal |
| 1357 | 1375 |
| 1358 } // namespace net | 1376 } // namespace net |
| OLD | NEW |