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