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

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

Issue 981643002: Fix bug that would create unnecessary ConnectJobs in some cases. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix stuff Created 5 years, 9 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 "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/format_macros.h" 8 #include "base/format_macros.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 return false; 219 return false;
220 // So in order to be stalled, |this| must be using at least |max_sockets_| AND 220 // So in order to be stalled, |this| must be using at least |max_sockets_| AND
221 // |this| must have a request that is actually stalled on the global socket 221 // |this| must have a request that is actually stalled on the global socket
222 // limit. To find such a request, look for a group that has more requests 222 // limit. To find such a request, look for a group that has more requests
223 // than jobs AND where the number of sockets is less than 223 // than jobs AND where the number of sockets is less than
224 // |max_sockets_per_group_|. (If the number of sockets is equal to 224 // |max_sockets_per_group_|. (If the number of sockets is equal to
225 // |max_sockets_per_group_|, then the request is stalled on the group limit, 225 // |max_sockets_per_group_|, then the request is stalled on the group limit,
226 // which does not count.) 226 // which does not count.)
227 for (GroupMap::const_iterator it = group_map_.begin(); 227 for (GroupMap::const_iterator it = group_map_.begin();
228 it != group_map_.end(); ++it) { 228 it != group_map_.end(); ++it) {
229 if (it->second->IsStalledOnPoolMaxSockets(max_sockets_per_group_)) 229 if (it->second->CanUseAdditionalSocketSlot(max_sockets_per_group_))
230 return true; 230 return true;
231 } 231 }
232 return false; 232 return false;
233 } 233 }
234 234
235 void ClientSocketPoolBaseHelper::AddLowerLayeredPool( 235 void ClientSocketPoolBaseHelper::AddLowerLayeredPool(
236 LowerLayeredPool* lower_pool) { 236 LowerLayeredPool* lower_pool) {
237 DCHECK(pool_); 237 DCHECK(pool_);
238 CHECK(!ContainsKey(lower_pools_, lower_pool)); 238 CHECK(!ContainsKey(lower_pools_, lower_pool));
239 lower_pools_.insert(lower_pool); 239 lower_pools_.insert(lower_pool);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 if (rv != ERR_IO_PENDING) { 271 if (rv != ERR_IO_PENDING) {
272 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); 272 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv);
273 CHECK(!request->handle()->is_initialized()); 273 CHECK(!request->handle()->is_initialized());
274 request.reset(); 274 request.reset();
275 } else { 275 } else {
276 group->InsertPendingRequest(request.Pass()); 276 group->InsertPendingRequest(request.Pass());
277 // Have to do this asynchronously, as closing sockets in higher level pools 277 // Have to do this asynchronously, as closing sockets in higher level pools
278 // call back in to |this|, which will cause all sorts of fun and exciting 278 // call back in to |this|, which will cause all sorts of fun and exciting
279 // re-entrancy issues if the socket pool is doing something else at the 279 // re-entrancy issues if the socket pool is doing something else at the
280 // time. 280 // time.
281 if (group->IsStalledOnPoolMaxSockets(max_sockets_per_group_)) { 281 if (group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) {
282 base::MessageLoop::current()->PostTask( 282 base::MessageLoop::current()->PostTask(
283 FROM_HERE, 283 FROM_HERE,
284 base::Bind( 284 base::Bind(
285 &ClientSocketPoolBaseHelper::TryToCloseSocketsInLayeredPools, 285 &ClientSocketPoolBaseHelper::TryToCloseSocketsInLayeredPools,
286 weak_factory_.GetWeakPtr())); 286 weak_factory_.GetWeakPtr()));
287 } 287 }
288 } 288 }
289 return rv; 289 return rv;
290 } 290 }
291 291
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 if (group.HasConnectJobForHandle(handle)) { 571 if (group.HasConnectJobForHandle(handle)) {
572 // Just return the state of the farthest along ConnectJob for the first 572 // Just return the state of the farthest along ConnectJob for the first
573 // group.jobs().size() pending requests. 573 // group.jobs().size() pending requests.
574 LoadState max_state = LOAD_STATE_IDLE; 574 LoadState max_state = LOAD_STATE_IDLE;
575 for (const auto& job : group.jobs()) { 575 for (const auto& job : group.jobs()) {
576 max_state = std::max(max_state, job->GetLoadState()); 576 max_state = std::max(max_state, job->GetLoadState());
577 } 577 }
578 return max_state; 578 return max_state;
579 } 579 }
580 580
581 if (group.IsStalledOnPoolMaxSockets(max_sockets_per_group_)) 581 if (group.CanUseAdditionalSocketSlot(max_sockets_per_group_))
582 return LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL; 582 return LOAD_STATE_WAITING_FOR_STALLED_SOCKET_POOL;
583 return LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET; 583 return LOAD_STATE_WAITING_FOR_AVAILABLE_SOCKET;
584 } 584 }
585 585
586 base::DictionaryValue* ClientSocketPoolBaseHelper::GetInfoAsValue( 586 base::DictionaryValue* ClientSocketPoolBaseHelper::GetInfoAsValue(
587 const std::string& name, const std::string& type) const { 587 const std::string& name, const std::string& type) const {
588 base::DictionaryValue* dict = new base::DictionaryValue(); 588 base::DictionaryValue* dict = new base::DictionaryValue();
589 dict->SetString("name", name); 589 dict->SetString("name", name);
590 dict->SetString("type", type); 590 dict->SetString("type", type);
591 dict->SetInteger("handed_out_socket_count", handed_out_socket_count_); 591 dict->SetInteger("handed_out_socket_count", handed_out_socket_count_);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 group_dict->Set("idle_sockets", idle_socket_list); 625 group_dict->Set("idle_sockets", idle_socket_list);
626 626
627 base::ListValue* connect_jobs_list = new base::ListValue(); 627 base::ListValue* connect_jobs_list = new base::ListValue();
628 std::set<ConnectJob*>::const_iterator job = group->jobs().begin(); 628 std::set<ConnectJob*>::const_iterator job = group->jobs().begin();
629 for (job = group->jobs().begin(); job != group->jobs().end(); job++) { 629 for (job = group->jobs().begin(); job != group->jobs().end(); job++) {
630 int source_id = (*job)->net_log().source().id; 630 int source_id = (*job)->net_log().source().id;
631 connect_jobs_list->Append(new base::FundamentalValue(source_id)); 631 connect_jobs_list->Append(new base::FundamentalValue(source_id));
632 } 632 }
633 group_dict->Set("connect_jobs", connect_jobs_list); 633 group_dict->Set("connect_jobs", connect_jobs_list);
634 634
635 group_dict->SetBoolean("is_stalled", 635 group_dict->SetBoolean("is_stalled", group->CanUseAdditionalSocketSlot(
636 group->IsStalledOnPoolMaxSockets( 636 max_sockets_per_group_));
637 max_sockets_per_group_));
638 group_dict->SetBoolean("backup_job_timer_is_running", 637 group_dict->SetBoolean("backup_job_timer_is_running",
639 group->BackupJobTimerIsRunning()); 638 group->BackupJobTimerIsRunning());
640 639
641 all_groups_dict->SetWithoutPathExpansion(it->first, group_dict); 640 all_groups_dict->SetWithoutPathExpansion(it->first, group_dict);
642 } 641 }
643 dict->Set("groups", all_groups_dict); 642 dict->Set("groups", all_groups_dict);
644 return dict; 643 return dict;
645 } 644 }
646 645
647 bool ClientSocketPoolBaseHelper::IdleSocket::IsUsable() const { 646 bool ClientSocketPoolBaseHelper::IdleSocket::IsUsable() const {
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 std::string* group_name) const { 828 std::string* group_name) const {
830 CHECK((group && group_name) || (!group && !group_name)); 829 CHECK((group && group_name) || (!group && !group_name));
831 Group* top_group = NULL; 830 Group* top_group = NULL;
832 const std::string* top_group_name = NULL; 831 const std::string* top_group_name = NULL;
833 bool has_stalled_group = false; 832 bool has_stalled_group = false;
834 for (GroupMap::const_iterator i = group_map_.begin(); 833 for (GroupMap::const_iterator i = group_map_.begin();
835 i != group_map_.end(); ++i) { 834 i != group_map_.end(); ++i) {
836 Group* curr_group = i->second; 835 Group* curr_group = i->second;
837 if (!curr_group->has_pending_requests()) 836 if (!curr_group->has_pending_requests())
838 continue; 837 continue;
839 if (curr_group->IsStalledOnPoolMaxSockets(max_sockets_per_group_)) { 838 if (curr_group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) {
840 if (!group) 839 if (!group)
841 return true; 840 return true;
842 has_stalled_group = true; 841 has_stalled_group = true;
843 bool has_higher_priority = !top_group || 842 bool has_higher_priority = !top_group ||
844 curr_group->TopPendingPriority() > top_group->TopPendingPriority(); 843 curr_group->TopPendingPriority() > top_group->TopPendingPriority();
845 if (has_higher_priority) { 844 if (has_higher_priority) {
846 top_group = curr_group; 845 top_group = curr_group;
847 top_group_name = &i->first; 846 top_group_name = &i->first;
848 } 847 }
849 } 848 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 connect_timing, request->handle(), base::TimeDelta(), 912 connect_timing, request->handle(), base::TimeDelta(),
914 group, request->net_log()); 913 group, request->net_log());
915 } 914 }
916 request->net_log().EndEventWithNetErrorCode( 915 request->net_log().EndEventWithNetErrorCode(
917 NetLog::TYPE_SOCKET_POOL, result); 916 NetLog::TYPE_SOCKET_POOL, result);
918 InvokeUserCallbackLater(request->handle(), request->callback(), result); 917 InvokeUserCallbackLater(request->handle(), request->callback(), result);
919 } else { 918 } else {
920 RemoveConnectJob(job, group); 919 RemoveConnectJob(job, group);
921 } 920 }
922 if (!handed_out_socket) { 921 if (!handed_out_socket) {
923 OnAvailableSocketSlot(group_name, group); 922 OnAvailableSocketSlot(group_name, group);
mmenke 2015/03/04 22:48:43 The issue is this was resulting in always making a
924 CheckForStalledSocketGroups(); 923 CheckForStalledSocketGroups();
925 } 924 }
926 } 925 }
927 } 926 }
928 927
929 void ClientSocketPoolBaseHelper::OnIPAddressChanged() { 928 void ClientSocketPoolBaseHelper::OnIPAddressChanged() {
930 FlushWithError(ERR_NETWORK_CHANGED); 929 FlushWithError(ERR_NETWORK_CHANGED);
931 } 930 }
932 931
933 void ClientSocketPoolBaseHelper::FlushWithError(int error) { 932 void ClientSocketPoolBaseHelper::FlushWithError(int error) {
(...skipping 19 matching lines...) Expand all
953 RemoveGroup(group_name); 952 RemoveGroup(group_name);
954 } else if (group->has_pending_requests()) { 953 } else if (group->has_pending_requests()) {
955 ProcessPendingRequest(group_name, group); 954 ProcessPendingRequest(group_name, group);
956 } 955 }
957 } 956 }
958 957
959 void ClientSocketPoolBaseHelper::ProcessPendingRequest( 958 void ClientSocketPoolBaseHelper::ProcessPendingRequest(
960 const std::string& group_name, Group* group) { 959 const std::string& group_name, Group* group) {
961 const Request* next_request = group->GetNextPendingRequest(); 960 const Request* next_request = group->GetNextPendingRequest();
962 DCHECK(next_request); 961 DCHECK(next_request);
962
963 // If the group has no idle sockets, and can't make use of an additional slot,
964 // either because it's at the limit or because it's at the socket per group
965 // limit, then there's nothing to do.
966 if (group->idle_sockets().empty() &&
967 !group->CanUseAdditionalSocketSlot(max_sockets_per_group_)) {
968 return;
969 }
970
963 int rv = RequestSocketInternal(group_name, *next_request); 971 int rv = RequestSocketInternal(group_name, *next_request);
964 if (rv != ERR_IO_PENDING) { 972 if (rv != ERR_IO_PENDING) {
965 scoped_ptr<const Request> request = group->PopNextPendingRequest(); 973 scoped_ptr<const Request> request = group->PopNextPendingRequest();
966 DCHECK(request); 974 DCHECK(request);
967 if (group->IsEmpty()) 975 if (group->IsEmpty())
968 RemoveGroup(group_name); 976 RemoveGroup(group_name);
969 977
970 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); 978 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv);
971 InvokeUserCallbackLater(request->handle(), request->callback(), rv); 979 InvokeUserCallbackLater(request->handle(), request->callback(), rv);
972 } 980 }
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
1322 pending_requests_.Erase(pointer); 1330 pending_requests_.Erase(pointer);
1323 // If there are no more requests, kill the backup timer. 1331 // If there are no more requests, kill the backup timer.
1324 if (pending_requests_.empty()) 1332 if (pending_requests_.empty())
1325 backup_job_timer_.Stop(); 1333 backup_job_timer_.Stop();
1326 return request.Pass(); 1334 return request.Pass();
1327 } 1335 }
1328 1336
1329 } // namespace internal 1337 } // namespace internal
1330 1338
1331 } // namespace net 1339 } // 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