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

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 comments. Created 3 years, 10 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 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;
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 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 // accessed. 973 // accessed.
961 NetLogWithSource job_log = job->net_log(); 974 NetLogWithSource job_log = job->net_log();
962 LoadTimingInfo::ConnectTiming connect_timing = job->connect_timing(); 975 LoadTimingInfo::ConnectTiming connect_timing = job->connect_timing();
963 976
964 // RemoveConnectJob(job, _) must be called by all branches below; 977 // RemoveConnectJob(job, _) must be called by all branches below;
965 // otherwise, |job| will be leaked. 978 // otherwise, |job| will be leaked.
966 979
967 if (result == OK) { 980 if (result == OK) {
968 DCHECK(socket.get()); 981 DCHECK(socket.get());
969 RemoveConnectJob(job, group); 982 RemoveConnectJob(job, group);
970 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); 983 std::unique_ptr<Request> request = group->PopNextPendingRequest();
971 if (request) { 984 if (request) {
972 LogBoundConnectJobToRequest(job_log.source(), *request); 985 LogBoundConnectJobToRequest(job_log.source(), *request);
973 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, 986 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED,
974 connect_timing, request->handle(), base::TimeDelta(), group, 987 connect_timing, request->handle(), base::TimeDelta(), group,
975 request->net_log()); 988 request->net_log());
976 request->net_log().EndEvent(NetLogEventType::SOCKET_POOL); 989 request->net_log().EndEvent(NetLogEventType::SOCKET_POOL);
977 InvokeUserCallbackLater(request->handle(), request->callback(), result); 990 InvokeUserCallbackLater(request->handle(), request->callback(), result);
978 } else { 991 } else {
979 AddIdleSocket(std::move(socket), group); 992 AddIdleSocket(std::move(socket), group);
980 OnAvailableSocketSlot(group_name, group); 993 OnAvailableSocketSlot(group_name, group);
981 CheckForStalledSocketGroups(); 994 CheckForStalledSocketGroups();
982 } 995 }
983 } else { 996 } else {
984 // If we got a socket, it must contain error information so pass that 997 // If we got a socket, it must contain error information so pass that
985 // up so that the caller can retrieve it. 998 // up so that the caller can retrieve it.
986 bool handed_out_socket = false; 999 bool handed_out_socket = false;
987 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); 1000 std::unique_ptr<Request> request = group->PopNextPendingRequest();
988 if (request) { 1001 if (request) {
989 LogBoundConnectJobToRequest(job_log.source(), *request); 1002 LogBoundConnectJobToRequest(job_log.source(), *request);
990 job->GetAdditionalErrorState(request->handle()); 1003 job->GetAdditionalErrorState(request->handle());
991 RemoveConnectJob(job, group); 1004 RemoveConnectJob(job, group);
992 if (socket.get()) { 1005 if (socket.get()) {
993 handed_out_socket = true; 1006 handed_out_socket = true;
994 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, 1007 HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED,
995 connect_timing, request->handle(), base::TimeDelta(), 1008 connect_timing, request->handle(), base::TimeDelta(),
996 group, request->net_log()); 1009 group, request->net_log());
997 } 1010 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 // If the group has no idle sockets, and can't make use of an additional slot, 1059 // If the group has no idle sockets, and can't make use of an additional slot,
1047 // either because it's at the limit or because it's at the socket per group 1060 // either because it's at the limit or because it's at the socket per group
1048 // limit, then there's nothing to do. 1061 // limit, then there's nothing to do.
1049 if (group->idle_sockets().empty() && 1062 if (group->idle_sockets().empty() &&
1050 !group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) { 1063 !group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) {
1051 return; 1064 return;
1052 } 1065 }
1053 1066
1054 int rv = RequestSocketInternal(group_name, *next_request); 1067 int rv = RequestSocketInternal(group_name, *next_request);
1055 if (rv != ERR_IO_PENDING) { 1068 if (rv != ERR_IO_PENDING) {
1056 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); 1069 std::unique_ptr<Request> request = group->PopNextPendingRequest();
1057 DCHECK(request); 1070 DCHECK(request);
1058 if (group->IsEmpty()) 1071 if (group->IsEmpty())
1059 RemoveGroup(group_name); 1072 RemoveGroup(group_name);
1060 1073
1061 request->net_log().EndEventWithNetErrorCode(NetLogEventType::SOCKET_POOL, 1074 request->net_log().EndEventWithNetErrorCode(NetLogEventType::SOCKET_POOL,
1062 rv); 1075 rv);
1063 InvokeUserCallbackLater(request->handle(), request->callback(), rv); 1076 InvokeUserCallbackLater(request->handle(), request->callback(), rv);
1064 } 1077 }
1065 } 1078 }
1066 1079
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 } 1146 }
1134 } 1147 }
1135 DCHECK_EQ(0, connecting_socket_count_); 1148 DCHECK_EQ(0, connecting_socket_count_);
1136 } 1149 }
1137 1150
1138 void ClientSocketPoolBaseHelper::CancelAllRequestsWithError(int error) { 1151 void ClientSocketPoolBaseHelper::CancelAllRequestsWithError(int error) {
1139 for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end();) { 1152 for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end();) {
1140 Group* group = i->second; 1153 Group* group = i->second;
1141 1154
1142 while (true) { 1155 while (true) {
1143 std::unique_ptr<const Request> request = group->PopNextPendingRequest(); 1156 std::unique_ptr<Request> request = group->PopNextPendingRequest();
1144 if (!request) 1157 if (!request)
1145 break; 1158 break;
1146 InvokeUserCallbackLater(request->handle(), request->callback(), error); 1159 InvokeUserCallbackLater(request->handle(), request->callback(), error);
1147 } 1160 }
1148 1161
1149 // Delete group if no longer needed. 1162 // Delete group if no longer needed.
1150 if (group->IsEmpty()) { 1163 if (group->IsEmpty()) {
1151 // RemoveGroup() will call .erase() which will invalidate the iterator, 1164 // RemoveGroup() will call .erase() which will invalidate the iterator,
1152 // but i will already have been incremented to a valid iterator before 1165 // but i will already have been incremented to a valid iterator before
1153 // RemoveGroup() is called. 1166 // RemoveGroup() is called.
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1376 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); 1389 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax();
1377 !pointer.is_null() && i < jobs_.size(); 1390 !pointer.is_null() && i < jobs_.size();
1378 pointer = pending_requests_.GetNextTowardsLastMin(pointer), ++i) { 1391 pointer = pending_requests_.GetNextTowardsLastMin(pointer), ++i) {
1379 if (pointer.value()->handle() == handle) 1392 if (pointer.value()->handle() == handle)
1380 return true; 1393 return true;
1381 } 1394 }
1382 return false; 1395 return false;
1383 } 1396 }
1384 1397
1385 void ClientSocketPoolBaseHelper::Group::InsertPendingRequest( 1398 void ClientSocketPoolBaseHelper::Group::InsertPendingRequest(
1386 std::unique_ptr<const Request> request) { 1399 std::unique_ptr<Request> request) {
1387 // This value must be cached before we release |request|. 1400 // This value must be cached before we release |request|.
1388 RequestPriority priority = request->priority(); 1401 RequestPriority priority = request->priority();
1389 if (request->respect_limits() == ClientSocketPool::RespectLimits::DISABLED) { 1402 if (request->respect_limits() == ClientSocketPool::RespectLimits::DISABLED) {
1390 // Put requests with RespectLimits::DISABLED (which should have 1403 // Put requests with RespectLimits::DISABLED (which should have
1391 // priority == MAXIMUM_PRIORITY) ahead of other requests with 1404 // priority == MAXIMUM_PRIORITY) ahead of other requests with
1392 // MAXIMUM_PRIORITY. 1405 // MAXIMUM_PRIORITY.
1393 DCHECK_EQ(priority, MAXIMUM_PRIORITY); 1406 DCHECK_EQ(priority, MAXIMUM_PRIORITY);
1394 pending_requests_.InsertAtFront(request.release(), priority); 1407 pending_requests_.InsertAtFront(request.release(), priority);
1395 } else { 1408 } else {
1396 pending_requests_.Insert(request.release(), priority); 1409 pending_requests_.Insert(request.release(), priority);
1397 } 1410 }
1398 } 1411 }
1399 1412
1400 std::unique_ptr<const ClientSocketPoolBaseHelper::Request> 1413 std::unique_ptr<ClientSocketPoolBaseHelper::Request>
1401 ClientSocketPoolBaseHelper::Group::PopNextPendingRequest() { 1414 ClientSocketPoolBaseHelper::Group::PopNextPendingRequest() {
1402 if (pending_requests_.empty()) 1415 if (pending_requests_.empty())
1403 return std::unique_ptr<const ClientSocketPoolBaseHelper::Request>(); 1416 return std::unique_ptr<ClientSocketPoolBaseHelper::Request>();
1404 return RemovePendingRequest(pending_requests_.FirstMax()); 1417 return RemovePendingRequest(pending_requests_.FirstMax());
1405 } 1418 }
1406 1419
1407 std::unique_ptr<const ClientSocketPoolBaseHelper::Request> 1420 std::unique_ptr<ClientSocketPoolBaseHelper::Request>
1408 ClientSocketPoolBaseHelper::Group::FindAndRemovePendingRequest( 1421 ClientSocketPoolBaseHelper::Group::FindAndRemovePendingRequest(
1409 ClientSocketHandle* handle) { 1422 ClientSocketHandle* handle) {
1410 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax(); 1423 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax();
1411 !pointer.is_null(); 1424 !pointer.is_null();
1412 pointer = pending_requests_.GetNextTowardsLastMin(pointer)) { 1425 pointer = pending_requests_.GetNextTowardsLastMin(pointer)) {
1413 if (pointer.value()->handle() == handle) { 1426 if (pointer.value()->handle() == handle) {
1414 std::unique_ptr<const Request> request = RemovePendingRequest(pointer); 1427 DCHECK_EQ(static_cast<RequestPriority>(pointer.priority()),
1428 pointer.value()->priority());
1429 std::unique_ptr<Request> request = RemovePendingRequest(pointer);
1415 return request; 1430 return request;
1416 } 1431 }
1417 } 1432 }
1418 return std::unique_ptr<const ClientSocketPoolBaseHelper::Request>(); 1433 return std::unique_ptr<ClientSocketPoolBaseHelper::Request>();
1419 } 1434 }
1420 1435
1421 std::unique_ptr<const ClientSocketPoolBaseHelper::Request> 1436 void ClientSocketPoolBaseHelper::Group::SetPriority(ClientSocketHandle* handle,
1437 RequestPriority priority) {
1438 for (RequestQueue::Pointer pointer = pending_requests_.FirstMax();
1439 !pointer.is_null();
1440 pointer = pending_requests_.GetNextTowardsLastMin(pointer)) {
1441 if (pointer.value()->handle() == handle) {
1442 if (pointer.value()->priority() == priority)
1443 return;
1444
1445 std::unique_ptr<Request> request = RemovePendingRequest(pointer);
1446
1447 // Requests that ignore limits much be created and remain at the highest
1448 // priority, and should not be reprioritized.
1449 DCHECK_EQ(request->respect_limits(),
1450 ClientSocketPool::RespectLimits::ENABLED);
1451
1452 request->set_priority(priority);
1453 InsertPendingRequest(std::move(request));
1454 return;
1455 }
1456 }
1457
1458 // This function must be called with a valid ClientSocketHandle.
1459 NOTREACHED();
1460 }
1461
1462 std::unique_ptr<ClientSocketPoolBaseHelper::Request>
1422 ClientSocketPoolBaseHelper::Group::RemovePendingRequest( 1463 ClientSocketPoolBaseHelper::Group::RemovePendingRequest(
1423 const RequestQueue::Pointer& pointer) { 1464 const RequestQueue::Pointer& pointer) {
1424 // TODO(eroman): Temporary for debugging http://crbug.com/467797. 1465 // TODO(eroman): Temporary for debugging http://crbug.com/467797.
1425 CHECK(!pointer.is_null()); 1466 CHECK(!pointer.is_null());
1426 std::unique_ptr<const Request> request(pointer.value()); 1467 std::unique_ptr<Request> request(pointer.value());
1427 pending_requests_.Erase(pointer); 1468 pending_requests_.Erase(pointer);
1428 // If there are no more requests, kill the backup timer. 1469 // If there are no more requests, kill the backup timer.
1429 if (pending_requests_.empty()) 1470 if (pending_requests_.empty())
1430 backup_job_timer_.Stop(); 1471 backup_job_timer_.Stop();
1431 request->CrashIfInvalid(); 1472 request->CrashIfInvalid();
1432 return request; 1473 return request;
1433 } 1474 }
1434 1475
1435 } // namespace internal 1476 } // namespace internal
1436 1477
1437 } // namespace net 1478 } // 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