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

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: Test for not propagating priority in HttpStreamFactoryImpl::Job if the stream's been returned alrea… Created 3 years, 11 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 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 298
299 void ClientSocketPoolBaseHelper::RemoveHigherLayeredPool( 299 void ClientSocketPoolBaseHelper::RemoveHigherLayeredPool(
300 HigherLayeredPool* higher_pool) { 300 HigherLayeredPool* higher_pool) {
301 CHECK(higher_pool); 301 CHECK(higher_pool);
302 CHECK(base::ContainsKey(higher_pools_, higher_pool)); 302 CHECK(base::ContainsKey(higher_pools_, higher_pool));
303 higher_pools_.erase(higher_pool); 303 higher_pools_.erase(higher_pool);
304 } 304 }
305 305
306 int ClientSocketPoolBaseHelper::RequestSocket( 306 int ClientSocketPoolBaseHelper::RequestSocket(
307 const std::string& group_name, 307 const std::string& group_name,
308 std::unique_ptr<const Request> request) { 308 std::unique_ptr<Request> request) {
309 CHECK(!request->callback().is_null()); 309 CHECK(!request->callback().is_null());
310 CHECK(request->handle()); 310 CHECK(request->handle());
311 311
312 // Cleanup any timed-out idle sockets. 312 // Cleanup any timed-out idle sockets.
313 CleanupIdleSockets(false); 313 CleanupIdleSockets(false);
314 314
315 request->net_log().BeginEvent(NetLogEventType::SOCKET_POOL); 315 request->net_log().BeginEvent(NetLogEventType::SOCKET_POOL);
316 Group* group = GetOrCreateGroup(group_name); 316 Group* group = GetOrCreateGroup(group_name);
317 317
318 int rv = RequestSocketInternal(group_name, *request); 318 int rv = RequestSocketInternal(group_name, *request);
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 } 555 }
556 556
557 // static 557 // static
558 void ClientSocketPoolBaseHelper::LogBoundConnectJobToRequest( 558 void ClientSocketPoolBaseHelper::LogBoundConnectJobToRequest(
559 const NetLogSource& connect_job_source, 559 const NetLogSource& connect_job_source,
560 const Request& request) { 560 const Request& request) {
561 request.net_log().AddEvent(NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB, 561 request.net_log().AddEvent(NetLogEventType::SOCKET_POOL_BOUND_TO_CONNECT_JOB,
562 connect_job_source.ToEventParametersCallback()); 562 connect_job_source.ToEventParametersCallback());
563 } 563 }
564 564
565 void ClientSocketPoolBaseHelper::SetPriority(const std::string& group_name,
566 ClientSocketHandle* handle,
567 RequestPriority priority) {
568 GroupMap::iterator group_it = group_map_.find(group_name);
569 if (group_it == group_map_.end()) {
570 DCHECK(base::ContainsKey(pending_callback_map_, handle));
571 // The Request has already completed and been destroyed; nothing to
572 // reprioritize.
573 return;
mmenke 2017/01/03 22:51:22 Per earlier comment, the ClientSocketHandle knows
Randy Smith (Not in Mondays) 2017/01/05 03:47:18 I'm embarrassed to say that when I first read your
574 }
575
576 group_it->second->SetPriority(handle, priority);
577 }
578
565 void ClientSocketPoolBaseHelper::CancelRequest( 579 void ClientSocketPoolBaseHelper::CancelRequest(
566 const std::string& group_name, ClientSocketHandle* handle) { 580 const std::string& group_name, ClientSocketHandle* handle) {
567 PendingCallbackMap::iterator callback_it = pending_callback_map_.find(handle); 581 PendingCallbackMap::iterator callback_it = pending_callback_map_.find(handle);
568 if (callback_it != pending_callback_map_.end()) { 582 if (callback_it != pending_callback_map_.end()) {
569 int result = callback_it->second.result; 583 int result = callback_it->second.result;
570 pending_callback_map_.erase(callback_it); 584 pending_callback_map_.erase(callback_it);
571 std::unique_ptr<StreamSocket> socket = handle->PassSocket(); 585 std::unique_ptr<StreamSocket> socket = handle->PassSocket();
572 if (socket) { 586 if (socket) {
573 if (result != OK) 587 if (result != OK)
574 socket->Disconnect(); 588 socket->Disconnect();
575 ReleaseSocket(handle->group_name(), std::move(socket), handle->id()); 589 ReleaseSocket(handle->group_name(), std::move(socket), handle->id());
576 } 590 }
577 return; 591 return;
578 } 592 }
579 593
580 CHECK(base::ContainsKey(group_map_, group_name)); 594 CHECK(base::ContainsKey(group_map_, group_name));
581 595
582 Group* group = GetOrCreateGroup(group_name); 596 Group* group = GetOrCreateGroup(group_name);
583 597
584 // Search pending_requests for matching handle. 598 // Search pending_requests for matching handle.
585 std::unique_ptr<const Request> request = 599 std::unique_ptr<Request> request = group->FindAndRemovePendingRequest(handle);
586 group->FindAndRemovePendingRequest(handle);
587 if (request) { 600 if (request) {
588 request->net_log().AddEvent(NetLogEventType::CANCELLED); 601 request->net_log().AddEvent(NetLogEventType::CANCELLED);
589 request->net_log().EndEvent(NetLogEventType::SOCKET_POOL); 602 request->net_log().EndEvent(NetLogEventType::SOCKET_POOL);
590 603
591 // We let the job run, unless we're at the socket limit and there is 604 // We let the job run, unless we're at the socket limit and there is
592 // not another request waiting on the job. 605 // not another request waiting on the job.
593 if (group->jobs().size() > group->pending_request_count() && 606 if (group->jobs().size() > group->pending_request_count() &&
594 ReachedMaxSocketsLimit()) { 607 ReachedMaxSocketsLimit()) {
595 RemoveConnectJob(group->jobs().begin()->get(), group); 608 RemoveConnectJob(group->jobs().begin()->get(), group);
596 CheckForStalledSocketGroups(); 609 CheckForStalledSocketGroups();
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 // accessed. 953 // accessed.
941 NetLogWithSource job_log = job->net_log(); 954 NetLogWithSource job_log = job->net_log();
942 LoadTimingInfo::ConnectTiming connect_timing = job->connect_timing(); 955 LoadTimingInfo::ConnectTiming connect_timing = job->connect_timing();
943 956
944 // RemoveConnectJob(job, _) must be called by all branches below; 957 // RemoveConnectJob(job, _) must be called by all branches below;
945 // otherwise, |job| will be leaked. 958 // otherwise, |job| will be leaked.
946 959
947 if (result == OK) { 960 if (result == OK) {
948 DCHECK(socket.get()); 961 DCHECK(socket.get());
949 RemoveConnectJob(job, group); 962 RemoveConnectJob(job, group);
950 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); 963 std::unique_ptr<Request> request = group->PopNextPendingRequest();
951 if (request) { 964 if (request) {
952 LogBoundConnectJobToRequest(job_log.source(), *request); 965 LogBoundConnectJobToRequest(job_log.source(), *request);
953 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, 966 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED,
954 connect_timing, request->handle(), base::TimeDelta(), group, 967 connect_timing, request->handle(), base::TimeDelta(), group,
955 request->net_log()); 968 request->net_log());
956 request->net_log().EndEvent(NetLogEventType::SOCKET_POOL); 969 request->net_log().EndEvent(NetLogEventType::SOCKET_POOL);
957 InvokeUserCallbackLater(request->handle(), request->callback(), result); 970 InvokeUserCallbackLater(request->handle(), request->callback(), result);
958 } else { 971 } else {
959 AddIdleSocket(std::move(socket), group); 972 AddIdleSocket(std::move(socket), group);
960 OnAvailableSocketSlot(group_name, group); 973 OnAvailableSocketSlot(group_name, group);
961 CheckForStalledSocketGroups(); 974 CheckForStalledSocketGroups();
962 } 975 }
963 } else { 976 } else {
964 // If we got a socket, it must contain error information so pass that 977 // If we got a socket, it must contain error information so pass that
965 // up so that the caller can retrieve it. 978 // up so that the caller can retrieve it.
966 bool handed_out_socket = false; 979 bool handed_out_socket = false;
967 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); 980 std::unique_ptr<Request> request = group->PopNextPendingRequest();
968 if (request) { 981 if (request) {
969 LogBoundConnectJobToRequest(job_log.source(), *request); 982 LogBoundConnectJobToRequest(job_log.source(), *request);
970 job->GetAdditionalErrorState(request->handle()); 983 job->GetAdditionalErrorState(request->handle());
971 RemoveConnectJob(job, group); 984 RemoveConnectJob(job, group);
972 if (socket.get()) { 985 if (socket.get()) {
973 handed_out_socket = true; 986 handed_out_socket = true;
974 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, 987 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED,
975 connect_timing, request->handle(), base::TimeDelta(), 988 connect_timing, request->handle(), base::TimeDelta(),
976 group, request->net_log()); 989 group, request->net_log());
977 } 990 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 // If the group has no idle sockets, and can't make use of an additional slot, 1039 // If the group has no idle sockets, and can't make use of an additional slot,
1027 // either because it's at the limit or because it's at the socket per group 1040 // either because it's at the limit or because it's at the socket per group
1028 // limit, then there's nothing to do. 1041 // limit, then there's nothing to do.
1029 if (group->idle_sockets().empty() && 1042 if (group->idle_sockets().empty() &&
1030 !group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) { 1043 !group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) {
1031 return; 1044 return;
1032 } 1045 }
1033 1046
1034 int rv = RequestSocketInternal(group_name, *next_request); 1047 int rv = RequestSocketInternal(group_name, *next_request);
1035 if (rv != ERR_IO_PENDING) { 1048 if (rv != ERR_IO_PENDING) {
1036 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); 1049 std::unique_ptr<Request> request = group->PopNextPendingRequest();
1037 DCHECK(request); 1050 DCHECK(request);
1038 if (group->IsEmpty()) 1051 if (group->IsEmpty())
1039 RemoveGroup(group_name); 1052 RemoveGroup(group_name);
1040 1053
1041 request->net_log().EndEventWithNetErrorCode(NetLogEventType::SOCKET_POOL, 1054 request->net_log().EndEventWithNetErrorCode(NetLogEventType::SOCKET_POOL,
1042 rv); 1055 rv);
1043 InvokeUserCallbackLater(request->handle(), request->callback(), rv); 1056 InvokeUserCallbackLater(request->handle(), request->callback(), rv);
1044 } 1057 }
1045 } 1058 }
1046 1059
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 } 1126 }
1114 } 1127 }
1115 DCHECK_EQ(0, connecting_socket_count_); 1128 DCHECK_EQ(0, connecting_socket_count_);
1116 } 1129 }
1117 1130
1118 void ClientSocketPoolBaseHelper::CancelAllRequestsWithError(int error) { 1131 void ClientSocketPoolBaseHelper::CancelAllRequestsWithError(int error) {
1119 for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end();) { 1132 for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end();) {
1120 Group* group = i->second; 1133 Group* group = i->second;
1121 1134
1122 while (true) { 1135 while (true) {
1123 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); 1136 std::unique_ptr<Request> request = group->PopNextPendingRequest();
1124 if (!request) 1137 if (!request)
1125 break; 1138 break;
1126 InvokeUserCallbackLater(request->handle(), request->callback(), error); 1139 InvokeUserCallbackLater(request->handle(), request->callback(), error);
1127 } 1140 }
1128 1141
1129 // Delete group if no longer needed. 1142 // Delete group if no longer needed.
1130 if (group->IsEmpty()) { 1143 if (group->IsEmpty()) {
1131 // RemoveGroup() will call .erase() which will invalidate the iterator, 1144 // RemoveGroup() will call .erase() which will invalidate the iterator,
1132 // but i will already have been incremented to a valid iterator before 1145 // but i will already have been incremented to a valid iterator before
1133 // RemoveGroup() is called. 1146 // RemoveGroup() is called.
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); 1369 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax();
1357 !pointer.is_null() && i < jobs_.size(); 1370 !pointer.is_null() && i < jobs_.size();
1358 pointer = pending_requests_.GetNextTowardsLastMin(pointer), ++i) { 1371 pointer = pending_requests_.GetNextTowardsLastMin(pointer), ++i) {
1359 if (pointer.value()->handle() == handle) 1372 if (pointer.value()->handle() == handle)
1360 return true; 1373 return true;
1361 } 1374 }
1362 return false; 1375 return false;
1363 } 1376 }
1364 1377
1365 void ClientSocketPoolBaseHelper::Group::InsertPendingRequest( 1378 void ClientSocketPoolBaseHelper::Group::InsertPendingRequest(
1366 std::unique_ptr<const Request> request) { 1379 std::unique_ptr<Request> request) {
1367 // This value must be cached before we release |request|. 1380 // This value must be cached before we release |request|.
1368 RequestPriority priority = request->priority(); 1381 RequestPriority priority = request->priority();
1369 if (request->respect_limits() == ClientSocketPool::RespectLimits::DISABLED) { 1382 if (request->respect_limits() == ClientSocketPool::RespectLimits::DISABLED) {
1370 // Put requests with RespectLimits::DISABLED (which should have 1383 // Put requests with RespectLimits::DISABLED (which should have
1371 // priority == MAXIMUM_PRIORITY) ahead of other requests with 1384 // priority == MAXIMUM_PRIORITY) ahead of other requests with
1372 // MAXIMUM_PRIORITY. 1385 // MAXIMUM_PRIORITY.
1373 DCHECK_EQ(priority, MAXIMUM_PRIORITY); 1386 DCHECK_EQ(priority, MAXIMUM_PRIORITY);
1374 pending_requests_.InsertAtFront(request.release(), priority); 1387 pending_requests_.InsertAtFront(request.release(), priority);
1375 } else { 1388 } else {
1376 pending_requests_.Insert(request.release(), priority); 1389 pending_requests_.Insert(request.release(), priority);
1377 } 1390 }
1378 } 1391 }
1379 1392
1380 std::unique_ptr<const ClientSocketPoolBaseHelper::Request> 1393 std::unique_ptr<ClientSocketPoolBaseHelper::Request>
1381 ClientSocketPoolBaseHelper::Group::PopNextPendingRequest() { 1394 ClientSocketPoolBaseHelper::Group::PopNextPendingRequest() {
1382 if (pending_requests_.empty()) 1395 if (pending_requests_.empty())
1383 return std::unique_ptr<const ClientSocketPoolBaseHelper::Request>(); 1396 return std::unique_ptr<ClientSocketPoolBaseHelper::Request>();
1384 return RemovePendingRequest(pending_requests_.FirstMax()); 1397 return RemovePendingRequest(pending_requests_.FirstMax());
1385 } 1398 }
1386 1399
1387 std::unique_ptr<const ClientSocketPoolBaseHelper::Request> 1400 std::unique_ptr<ClientSocketPoolBaseHelper::Request>
1388 ClientSocketPoolBaseHelper::Group::FindAndRemovePendingRequest( 1401 ClientSocketPoolBaseHelper::Group::FindAndRemovePendingRequest(
1389 ClientSocketHandle* handle) { 1402 ClientSocketHandle* handle) {
1390 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); 1403 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax();
1391 !pointer.is_null(); 1404 !pointer.is_null();
1392 pointer = pending_requests_.GetNextTowardsLastMin(pointer)) { 1405 pointer = pending_requests_.GetNextTowardsLastMin(pointer)) {
1393 if (pointer.value()->handle() == handle) { 1406 if (pointer.value()->handle() == handle) {
1394 std::unique_ptr<const Request> request = RemovePendingRequest(pointer); 1407 std::unique_ptr<Request> request = RemovePendingRequest(pointer);
1395 return request; 1408 return request;
1396 } 1409 }
1397 } 1410 }
1398 return std::unique_ptr<const ClientSocketPoolBaseHelper::Request>(); 1411 return std::unique_ptr<ClientSocketPoolBaseHelper::Request>();
1399 } 1412 }
1400 1413
1401 std::unique_ptr<const ClientSocketPoolBaseHelper::Request> 1414 void ClientSocketPoolBaseHelper::Group::SetPriority(ClientSocketHandle* handle,
1415 RequestPriority priority) {
1416 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax();
1417 !pointer.is_null();
1418 pointer = pending_requests_.GetNextTowardsLastMin(pointer)) {
1419 if (pointer.value()->handle() == handle) {
1420 if (pointer.priority() == priority)
1421 return;
1422
1423 std::unique_ptr<Request> request = RemovePendingRequest(pointer);
1424
1425 // Requests that ignore limits much be created and remain at the highest
1426 // priority, and should not be reprioritized.
1427 DCHECK_EQ(request->respect_limits(),
1428 ClientSocketPool::RespectLimits::ENABLED);
1429
1430 request->set_priority(priority);
1431 InsertPendingRequest(std::move(request));
1432 return;
1433 }
1434 }
mmenke 2017/01/03 22:51:22 This entire block is just: std::unique_ptr<Reques
Randy Smith (Not in Mondays) 2017/01/05 03:47:18 The entire reason for this code is indeed the case
Randy Smith (Not in Mondays) 2017/01/13 23:05:44 Ping?
mmenke 2017/01/17 18:56:31 Sorry, I was thinking the early return was a break
Randy Smith (Not in Mondays) 2017/01/17 19:50:36 So I'm quite happy to do #3; I changed it to this
Charlie Harrison 2017/01/17 20:04:39 I am OK with #3 as long as it is documented clearl
mmenke 2017/01/17 20:11:28 Could also do a DLOG(WARNING), though if DLOG's ar
1435
1436 // This function must be called with a valid ClientSocketHandle.
1437 NOTREACHED();
1438 }
1439
1440 std::unique_ptr<ClientSocketPoolBaseHelper::Request>
1402 ClientSocketPoolBaseHelper::Group::RemovePendingRequest( 1441 ClientSocketPoolBaseHelper::Group::RemovePendingRequest(
1403 const RequestQueue::Pointer& pointer) { 1442 const RequestQueue::Pointer& pointer) {
1404 // TODO(eroman): Temporary for debugging http://crbug.com/467797. 1443 // TODO(eroman): Temporary for debugging http://crbug.com/467797.
1405 CHECK(!pointer.is_null()); 1444 CHECK(!pointer.is_null());
1406 std::unique_ptr<const Request> request(pointer.value()); 1445 std::unique_ptr<Request> request(pointer.value());
1407 pending_requests_.Erase(pointer); 1446 pending_requests_.Erase(pointer);
1408 // If there are no more requests, kill the backup timer. 1447 // If there are no more requests, kill the backup timer.
1409 if (pending_requests_.empty()) 1448 if (pending_requests_.empty())
1410 backup_job_timer_.Stop(); 1449 backup_job_timer_.Stop();
1411 request->CrashIfInvalid(); 1450 request->CrashIfInvalid();
1412 return request; 1451 return request;
1413 } 1452 }
1414 1453
1415 } // namespace internal 1454 } // namespace internal
1416 1455
1417 } // namespace net 1456 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698