| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/metrics/stats_counters.h" | 10 #include "base/metrics/stats_counters.h" |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 | 243 |
| 244 Group* group = GetOrCreateGroup(group_name); | 244 Group* group = GetOrCreateGroup(group_name); |
| 245 | 245 |
| 246 // RequestSocketsInternal() may delete the group. | 246 // RequestSocketsInternal() may delete the group. |
| 247 bool deleted_group = false; | 247 bool deleted_group = false; |
| 248 | 248 |
| 249 for (int num_iterations_left = num_sockets; | 249 for (int num_iterations_left = num_sockets; |
| 250 group->NumActiveSocketSlots() < num_sockets && | 250 group->NumActiveSocketSlots() < num_sockets && |
| 251 num_iterations_left > 0 ; num_iterations_left--) { | 251 num_iterations_left > 0 ; num_iterations_left--) { |
| 252 int rv = RequestSocketInternal(group_name, &request); | 252 int rv = RequestSocketInternal(group_name, &request); |
| 253 // TODO(willchan): Possibly check for ERR_PRECONNECT_MAX_SOCKET_LIMIT so we |
| 254 // can log it into the NetLog. |
| 253 if (rv < 0 && rv != ERR_IO_PENDING) { | 255 if (rv < 0 && rv != ERR_IO_PENDING) { |
| 254 // We're encountering a synchronous error. Give up. | 256 // We're encountering a synchronous error. Give up. |
| 255 if (!ContainsKey(group_map_, group_name)) | 257 if (!ContainsKey(group_map_, group_name)) |
| 256 deleted_group = true; | 258 deleted_group = true; |
| 257 break; | 259 break; |
| 258 } | 260 } |
| 259 if (!ContainsKey(group_map_, group_name)) { | 261 if (!ContainsKey(group_map_, group_name)) { |
| 260 // Unexpected. The group should only be getting deleted on synchronous | 262 // Unexpected. The group should only be getting deleted on synchronous |
| 261 // error. | 263 // error. |
| 262 NOTREACHED(); | 264 NOTREACHED(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 291 | 293 |
| 292 // Can we make another active socket now? | 294 // Can we make another active socket now? |
| 293 if (!group->HasAvailableSocketSlot(max_sockets_per_group_)) { | 295 if (!group->HasAvailableSocketSlot(max_sockets_per_group_)) { |
| 294 request->net_log().AddEvent( | 296 request->net_log().AddEvent( |
| 295 NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS_PER_GROUP, NULL); | 297 NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS_PER_GROUP, NULL); |
| 296 return ERR_IO_PENDING; | 298 return ERR_IO_PENDING; |
| 297 } | 299 } |
| 298 | 300 |
| 299 if (ReachedMaxSocketsLimit()) { | 301 if (ReachedMaxSocketsLimit()) { |
| 300 if (idle_socket_count() > 0) { | 302 if (idle_socket_count() > 0) { |
| 301 CloseOneIdleSocket(); | 303 bool closed = CloseOneIdleSocketExceptInGroup(group); |
| 304 if (preconnecting && !closed) |
| 305 return ERR_PRECONNECT_MAX_SOCKET_LIMIT; |
| 302 } else { | 306 } else { |
| 303 // We could check if we really have a stalled group here, but it requires | 307 // We could check if we really have a stalled group here, but it requires |
| 304 // a scan of all groups, so just flip a flag here, and do the check later. | 308 // a scan of all groups, so just flip a flag here, and do the check later. |
| 305 request->net_log().AddEvent( | 309 request->net_log().AddEvent( |
| 306 NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS, NULL); | 310 NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS, NULL); |
| 307 return ERR_IO_PENDING; | 311 return ERR_IO_PENDING; |
| 308 } | 312 } |
| 309 } | 313 } |
| 310 | 314 |
| 311 // We couldn't find a socket to reuse, so allocate and connect a new one. | 315 // We couldn't find a socket to reuse, so allocate and connect a new one. |
| (...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 // Each connecting socket will eventually connect and be handed out. | 937 // Each connecting socket will eventually connect and be handed out. |
| 934 int total = handed_out_socket_count_ + connecting_socket_count_ + | 938 int total = handed_out_socket_count_ + connecting_socket_count_ + |
| 935 idle_socket_count(); | 939 idle_socket_count(); |
| 936 DCHECK_LE(total, max_sockets_); | 940 DCHECK_LE(total, max_sockets_); |
| 937 if (total < max_sockets_) | 941 if (total < max_sockets_) |
| 938 return false; | 942 return false; |
| 939 return true; | 943 return true; |
| 940 } | 944 } |
| 941 | 945 |
| 942 void ClientSocketPoolBaseHelper::CloseOneIdleSocket() { | 946 void ClientSocketPoolBaseHelper::CloseOneIdleSocket() { |
| 947 CloseOneIdleSocketExceptInGroup(NULL); |
| 948 } |
| 949 |
| 950 bool ClientSocketPoolBaseHelper::CloseOneIdleSocketExceptInGroup( |
| 951 const Group* exception_group) { |
| 943 CHECK_GT(idle_socket_count(), 0); | 952 CHECK_GT(idle_socket_count(), 0); |
| 944 | 953 |
| 945 for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end(); ++i) { | 954 for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end(); ++i) { |
| 946 Group* group = i->second; | 955 Group* group = i->second; |
| 956 if (exception_group == group) |
| 957 continue; |
| 947 std::list<IdleSocket>* idle_sockets = group->mutable_idle_sockets(); | 958 std::list<IdleSocket>* idle_sockets = group->mutable_idle_sockets(); |
| 948 | 959 |
| 949 if (!idle_sockets->empty()) { | 960 if (!idle_sockets->empty()) { |
| 950 delete idle_sockets->front().socket; | 961 delete idle_sockets->front().socket; |
| 951 idle_sockets->pop_front(); | 962 idle_sockets->pop_front(); |
| 952 DecrementIdleCount(); | 963 DecrementIdleCount(); |
| 953 if (group->IsEmpty()) | 964 if (group->IsEmpty()) |
| 954 RemoveGroup(i); | 965 RemoveGroup(i); |
| 955 | 966 |
| 956 return; | 967 return true; |
| 957 } | 968 } |
| 958 } | 969 } |
| 959 | 970 |
| 960 LOG(DFATAL) << "No idle socket found to close!."; | 971 if (!exception_group) |
| 972 LOG(DFATAL) << "No idle socket found to close!."; |
| 973 |
| 974 return false; |
| 961 } | 975 } |
| 962 | 976 |
| 963 void ClientSocketPoolBaseHelper::InvokeUserCallbackLater( | 977 void ClientSocketPoolBaseHelper::InvokeUserCallbackLater( |
| 964 ClientSocketHandle* handle, CompletionCallback* callback, int rv) { | 978 ClientSocketHandle* handle, CompletionCallback* callback, int rv) { |
| 965 CHECK(!ContainsKey(pending_callback_map_, handle)); | 979 CHECK(!ContainsKey(pending_callback_map_, handle)); |
| 966 pending_callback_map_[handle] = CallbackResultPair(callback, rv); | 980 pending_callback_map_[handle] = CallbackResultPair(callback, rv); |
| 967 MessageLoop::current()->PostTask( | 981 MessageLoop::current()->PostTask( |
| 968 FROM_HERE, | 982 FROM_HERE, |
| 969 method_factory_.NewRunnableMethod( | 983 method_factory_.NewRunnableMethod( |
| 970 &ClientSocketPoolBaseHelper::InvokeUserCallback, | 984 &ClientSocketPoolBaseHelper::InvokeUserCallback, |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 // Delete active jobs. | 1073 // Delete active jobs. |
| 1060 STLDeleteElements(&jobs_); | 1074 STLDeleteElements(&jobs_); |
| 1061 | 1075 |
| 1062 // Cancel pending backup job. | 1076 // Cancel pending backup job. |
| 1063 method_factory_.RevokeAll(); | 1077 method_factory_.RevokeAll(); |
| 1064 } | 1078 } |
| 1065 | 1079 |
| 1066 } // namespace internal | 1080 } // namespace internal |
| 1067 | 1081 |
| 1068 } // namespace net | 1082 } // namespace net |
| OLD | NEW |