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 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |