Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(632)

Side by Side Diff: net/socket/client_socket_pool_base.cc

Issue 1898133002: Add reprioritization to socket pools. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Incorporated Matt's comments. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698