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

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

Powered by Google App Engine
This is Rietveld 408576698