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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 request.net_log().BeginEvent( | 239 request.net_log().BeginEvent( |
240 NetLog::TYPE_SOCKET_POOL_CONNECTING_N_SOCKETS, | 240 NetLog::TYPE_SOCKET_POOL_CONNECTING_N_SOCKETS, |
241 make_scoped_refptr(new NetLogIntegerParameter( | 241 make_scoped_refptr(new NetLogIntegerParameter( |
242 "num_sockets", num_sockets))); | 242 "num_sockets", num_sockets))); |
243 | 243 |
244 Group* group = GetOrCreateGroup(group_name); | 244 Group* group = GetOrCreateGroup(group_name); |
245 | 245 |
246 for (int num_iterations_left = num_sockets; | 246 for (int num_iterations_left = num_sockets; |
247 group->NumActiveSocketSlots() < num_sockets && | 247 group->NumActiveSocketSlots() < num_sockets && |
248 num_iterations_left > 0 ; num_iterations_left--) { | 248 num_iterations_left > 0 ; num_iterations_left--) { |
249 int rv = RequestSocketInternal(group_name, &request); | 249 int rv = RequestSocketInternal(group_name, &request); |
willchan no longer on Chromium
2010/12/02 01:58:07
Should I special case ERR_PRECONNECT_MAX_SOCKET_LI
Mike Belshe
2010/12/02 02:46:48
It's up to you. Maybe add a TODO
| |
250 if (rv < 0 && rv != ERR_IO_PENDING) { | 250 if (rv < 0 && rv != ERR_IO_PENDING) { |
251 // We're encountering a synchronous error. Give up. | 251 // We're encountering a synchronous error. Give up. |
252 break; | 252 break; |
253 } | 253 } |
254 } | 254 } |
255 | 255 |
256 if (group->IsEmpty()) | 256 if (group->IsEmpty()) |
257 RemoveGroup(group_name); | 257 RemoveGroup(group_name); |
258 | 258 |
259 request.net_log().EndEvent( | 259 request.net_log().EndEvent( |
(...skipping 19 matching lines...) Expand all Loading... | |
279 | 279 |
280 // Can we make another active socket now? | 280 // Can we make another active socket now? |
281 if (!group->HasAvailableSocketSlot(max_sockets_per_group_)) { | 281 if (!group->HasAvailableSocketSlot(max_sockets_per_group_)) { |
282 request->net_log().AddEvent( | 282 request->net_log().AddEvent( |
283 NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS_PER_GROUP, NULL); | 283 NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS_PER_GROUP, NULL); |
284 return ERR_IO_PENDING; | 284 return ERR_IO_PENDING; |
285 } | 285 } |
286 | 286 |
287 if (ReachedMaxSocketsLimit()) { | 287 if (ReachedMaxSocketsLimit()) { |
288 if (idle_socket_count() > 0) { | 288 if (idle_socket_count() > 0) { |
289 CloseOneIdleSocket(); | 289 bool closed = CloseOneIdleSocketExceptInGroup(group); |
290 if (preconnecting && !closed) | |
291 return ERR_PRECONNECT_MAX_SOCKET_LIMIT; | |
290 } else { | 292 } else { |
291 // We could check if we really have a stalled group here, but it requires | 293 // We could check if we really have a stalled group here, but it requires |
292 // a scan of all groups, so just flip a flag here, and do the check later. | 294 // a scan of all groups, so just flip a flag here, and do the check later. |
293 request->net_log().AddEvent( | 295 request->net_log().AddEvent( |
294 NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS, NULL); | 296 NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS, NULL); |
295 return ERR_IO_PENDING; | 297 return ERR_IO_PENDING; |
296 } | 298 } |
297 } | 299 } |
298 | 300 |
299 // We couldn't find a socket to reuse, so allocate and connect a new one. | 301 // 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... | |
921 // Each connecting socket will eventually connect and be handed out. | 923 // Each connecting socket will eventually connect and be handed out. |
922 int total = handed_out_socket_count_ + connecting_socket_count_ + | 924 int total = handed_out_socket_count_ + connecting_socket_count_ + |
923 idle_socket_count(); | 925 idle_socket_count(); |
924 DCHECK_LE(total, max_sockets_); | 926 DCHECK_LE(total, max_sockets_); |
925 if (total < max_sockets_) | 927 if (total < max_sockets_) |
926 return false; | 928 return false; |
927 return true; | 929 return true; |
928 } | 930 } |
929 | 931 |
930 void ClientSocketPoolBaseHelper::CloseOneIdleSocket() { | 932 void ClientSocketPoolBaseHelper::CloseOneIdleSocket() { |
933 CloseOneIdleSocketExceptInGroup(NULL); | |
934 } | |
935 | |
936 bool ClientSocketPoolBaseHelper::CloseOneIdleSocketExceptInGroup( | |
937 const Group* exception_group) { | |
931 CHECK_GT(idle_socket_count(), 0); | 938 CHECK_GT(idle_socket_count(), 0); |
932 | 939 |
933 for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end(); ++i) { | 940 for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end(); ++i) { |
934 Group* group = i->second; | 941 Group* group = i->second; |
942 if (exception_group == group) | |
943 continue; | |
935 std::list<IdleSocket>* idle_sockets = group->mutable_idle_sockets(); | 944 std::list<IdleSocket>* idle_sockets = group->mutable_idle_sockets(); |
936 | 945 |
937 if (!idle_sockets->empty()) { | 946 if (!idle_sockets->empty()) { |
938 delete idle_sockets->front().socket; | 947 delete idle_sockets->front().socket; |
939 idle_sockets->pop_front(); | 948 idle_sockets->pop_front(); |
940 DecrementIdleCount(); | 949 DecrementIdleCount(); |
941 if (group->IsEmpty()) | 950 if (group->IsEmpty()) |
942 RemoveGroup(i); | 951 RemoveGroup(i); |
943 | 952 |
944 return; | 953 return true; |
945 } | 954 } |
946 } | 955 } |
947 | 956 |
948 LOG(DFATAL) << "No idle socket found to close!."; | 957 if (!exception_group) |
958 LOG(DFATAL) << "No idle socket found to close!."; | |
959 | |
960 return false; | |
949 } | 961 } |
950 | 962 |
951 void ClientSocketPoolBaseHelper::InvokeUserCallbackLater( | 963 void ClientSocketPoolBaseHelper::InvokeUserCallbackLater( |
952 ClientSocketHandle* handle, CompletionCallback* callback, int rv) { | 964 ClientSocketHandle* handle, CompletionCallback* callback, int rv) { |
953 CHECK(!ContainsKey(pending_callback_map_, handle)); | 965 CHECK(!ContainsKey(pending_callback_map_, handle)); |
954 pending_callback_map_[handle] = CallbackResultPair(callback, rv); | 966 pending_callback_map_[handle] = CallbackResultPair(callback, rv); |
955 MessageLoop::current()->PostTask( | 967 MessageLoop::current()->PostTask( |
956 FROM_HERE, | 968 FROM_HERE, |
957 method_factory_.NewRunnableMethod( | 969 method_factory_.NewRunnableMethod( |
958 &ClientSocketPoolBaseHelper::InvokeUserCallback, | 970 &ClientSocketPoolBaseHelper::InvokeUserCallback, |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1047 // Delete active jobs. | 1059 // Delete active jobs. |
1048 STLDeleteElements(&jobs_); | 1060 STLDeleteElements(&jobs_); |
1049 | 1061 |
1050 // Cancel pending backup job. | 1062 // Cancel pending backup job. |
1051 method_factory_.RevokeAll(); | 1063 method_factory_.RevokeAll(); |
1052 } | 1064 } |
1053 | 1065 |
1054 } // namespace internal | 1066 } // namespace internal |
1055 | 1067 |
1056 } // namespace net | 1068 } // namespace net |
OLD | NEW |