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

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

Issue 2888623011: Fix for HTTP2 request hanging bug. (Closed)
Patch Set: Created 3 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
« no previous file with comments | « no previous file | 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 884 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 OnAvailableSocketSlot(group_name, group); 895 OnAvailableSocketSlot(group_name, group);
896 } else { 896 } else {
897 socket.reset(); 897 socket.reset();
898 RecordIdleSocketFate(IDLE_SOCKET_FATE_RELEASE_UNUSABLE); 898 RecordIdleSocketFate(IDLE_SOCKET_FATE_RELEASE_UNUSABLE);
899 } 899 }
900 900
901 CheckForStalledSocketGroups(); 901 CheckForStalledSocketGroups();
902 } 902 }
903 903
904 void ClientSocketPoolBaseHelper::CheckForStalledSocketGroups() { 904 void ClientSocketPoolBaseHelper::CheckForStalledSocketGroups() {
905 // If we have idle sockets, see if we can give one to the top-stalled group. 905 // Loop until there's nothing more to do.
906 std::string top_group_name; 906 while (true) {
907 Group* top_group = NULL; 907 // If we have idle sockets, see if we can give one to the top-stalled group.
908 if (!FindTopStalledGroup(&top_group, &top_group_name)) { 908 std::string top_group_name;
909 // There may still be a stalled group in a lower level pool. 909 Group* top_group = NULL;
910 for (std::set<LowerLayeredPool*>::iterator it = lower_pools_.begin(); 910 if (!FindTopStalledGroup(&top_group, &top_group_name)) {
911 it != lower_pools_.end(); 911 // There may still be a stalled group in a lower level pool.
912 ++it) { 912 for (std::set<LowerLayeredPool*>::iterator it = lower_pools_.begin();
913 if ((*it)->IsStalled()) { 913 it != lower_pools_.end(); ++it) {
914 CloseOneIdleSocket(); 914 if ((*it)->IsStalled()) {
915 break; 915 CloseOneIdleSocket();
916 } 916 break;
davidben 2017/05/18 20:22:51 What's causing the socket pools to react to the fr
mmenke 2017/05/18 20:44:57 Destroying the socket will do that. So suppose th
davidben 2017/05/18 20:52:31 I guess the vague analogy to our sync-return || ER
mmenke 2017/05/18 21:00:43 Ideally, we really should only have at most one (n
917 } 917 }
918 return; 918 }
919 }
920
921 if (ReachedMaxSocketsLimit()) {
922 if (idle_socket_count() > 0) {
923 CloseOneIdleSocket();
924 } else {
925 // We can't activate more sockets since we're already at our global
926 // limit.
927 return; 919 return;
928 } 920 }
921
922 if (ReachedMaxSocketsLimit()) {
923 if (idle_socket_count() > 0) {
924 CloseOneIdleSocket();
925 } else {
926 // We can't activate more sockets since we're already at our global
927 // limit.
928 return;
929 }
930 }
931
932 // Note that this may delete top_group.
933 OnAvailableSocketSlot(top_group_name, top_group);
929 } 934 }
930
931 // Note: we don't loop on waking stalled groups. If the stalled group is at
932 // its limit, may be left with other stalled groups that could be
933 // woken. This isn't optimal, but there is no starvation, so to avoid
934 // the looping we leave it at this.
davidben 2017/05/18 20:22:51 Previously we tried to avoid infinite looping here
mmenke 2017/05/18 20:44:57 Correct. I can't see how we'd get into an infinit
935 OnAvailableSocketSlot(top_group_name, top_group);
936 } 935 }
937 936
938 // Search for the highest priority pending request, amongst the groups that 937 // Search for the highest priority pending request, amongst the groups that
939 // are not at the |max_sockets_per_group_| limit. Note: for requests with 938 // are not at the |max_sockets_per_group_| limit. Note: for requests with
940 // the same priority, the winner is based on group hash ordering (and not 939 // the same priority, the winner is based on group hash ordering (and not
941 // insertion order). 940 // insertion order).
942 bool ClientSocketPoolBaseHelper::FindTopStalledGroup( 941 bool ClientSocketPoolBaseHelper::FindTopStalledGroup(
943 Group** group, 942 Group** group,
944 std::string* group_name) const { 943 std::string* group_name) const {
945 CHECK((group && group_name) || (!group && !group_name)); 944 CHECK((group && group_name) || (!group && !group_name));
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 1072
1074 // If the group has no idle sockets, and can't make use of an additional slot, 1073 // If the group has no idle sockets, and can't make use of an additional slot,
1075 // either because it's at the limit or because it's at the socket per group 1074 // either because it's at the limit or because it's at the socket per group
1076 // limit, then there's nothing to do. 1075 // limit, then there's nothing to do.
1077 if (group->idle_sockets().empty() && 1076 if (group->idle_sockets().empty() &&
1078 !group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) { 1077 !group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) {
1079 return; 1078 return;
1080 } 1079 }
1081 1080
1082 int rv = RequestSocketInternal(group_name, *next_request); 1081 int rv = RequestSocketInternal(group_name, *next_request);
1083 if (rv != ERR_IO_PENDING) { 1082 if (rv != ERR_IO_PENDING) {
mmenke 2017/05/18 20:00:19 Could add a loop here, too, but: 1) group may be
1084 std::unique_ptr<Request> request = group->PopNextPendingRequest(); 1083 std::unique_ptr<Request> request = group->PopNextPendingRequest();
1085 DCHECK(request); 1084 DCHECK(request);
1086 if (group->IsEmpty()) 1085 if (group->IsEmpty())
1087 RemoveGroup(group_name); 1086 RemoveGroup(group_name);
1088 1087
1089 request->net_log().EndEventWithNetErrorCode(NetLogEventType::SOCKET_POOL, 1088 request->net_log().EndEventWithNetErrorCode(NetLogEventType::SOCKET_POOL,
1090 rv); 1089 rv);
1091 InvokeUserCallbackLater(request->handle(), request->callback(), rv); 1090 InvokeUserCallbackLater(request->handle(), request->callback(), rv);
1092 } 1091 }
1093 } 1092 }
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 // If there are no more requests, kill the backup timer. 1479 // If there are no more requests, kill the backup timer.
1481 if (pending_requests_.empty()) 1480 if (pending_requests_.empty())
1482 backup_job_timer_.Stop(); 1481 backup_job_timer_.Stop();
1483 request->CrashIfInvalid(); 1482 request->CrashIfInvalid();
1484 return request; 1483 return request;
1485 } 1484 }
1486 1485
1487 } // namespace internal 1486 } // namespace internal
1488 1487
1489 } // namespace net 1488 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/socket/client_socket_pool_base_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698