| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <math.h> | 7 #include <math.h> |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 | 154 |
| 155 net_log_.AddEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT, NULL); | 155 net_log_.AddEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT, NULL); |
| 156 | 156 |
| 157 NotifyDelegateOfCompletion(ERR_TIMED_OUT); | 157 NotifyDelegateOfCompletion(ERR_TIMED_OUT); |
| 158 } | 158 } |
| 159 | 159 |
| 160 namespace internal { | 160 namespace internal { |
| 161 | 161 |
| 162 ClientSocketPoolBaseHelper::Request::Request( | 162 ClientSocketPoolBaseHelper::Request::Request( |
| 163 ClientSocketHandle* handle, | 163 ClientSocketHandle* handle, |
| 164 OldCompletionCallback* callback, | 164 const CompletionCallback& callback, |
| 165 RequestPriority priority, | 165 RequestPriority priority, |
| 166 bool ignore_limits, | 166 bool ignore_limits, |
| 167 Flags flags, | 167 Flags flags, |
| 168 const BoundNetLog& net_log) | 168 const BoundNetLog& net_log) |
| 169 : handle_(handle), | 169 : handle_(handle), |
| 170 callback_(callback), | 170 callback_(callback), |
| 171 priority_(priority), | 171 priority_(priority), |
| 172 ignore_limits_(ignore_limits), | 172 ignore_limits_(ignore_limits), |
| 173 flags_(flags), | 173 flags_(flags), |
| 174 net_log_(net_log) {} | 174 net_log_(net_log) {} |
| (...skipping 10 matching lines...) Expand all Loading... |
| 185 connecting_socket_count_(0), | 185 connecting_socket_count_(0), |
| 186 handed_out_socket_count_(0), | 186 handed_out_socket_count_(0), |
| 187 max_sockets_(max_sockets), | 187 max_sockets_(max_sockets), |
| 188 max_sockets_per_group_(max_sockets_per_group), | 188 max_sockets_per_group_(max_sockets_per_group), |
| 189 use_cleanup_timer_(g_cleanup_timer_enabled), | 189 use_cleanup_timer_(g_cleanup_timer_enabled), |
| 190 unused_idle_socket_timeout_(unused_idle_socket_timeout), | 190 unused_idle_socket_timeout_(unused_idle_socket_timeout), |
| 191 used_idle_socket_timeout_(used_idle_socket_timeout), | 191 used_idle_socket_timeout_(used_idle_socket_timeout), |
| 192 connect_job_factory_(connect_job_factory), | 192 connect_job_factory_(connect_job_factory), |
| 193 connect_backup_jobs_enabled_(false), | 193 connect_backup_jobs_enabled_(false), |
| 194 pool_generation_number_(0), | 194 pool_generation_number_(0), |
| 195 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 195 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
| 196 DCHECK_LE(0, max_sockets_per_group); | 196 DCHECK_LE(0, max_sockets_per_group); |
| 197 DCHECK_LE(max_sockets_per_group, max_sockets); | 197 DCHECK_LE(max_sockets_per_group, max_sockets); |
| 198 | 198 |
| 199 NetworkChangeNotifier::AddIPAddressObserver(this); | 199 NetworkChangeNotifier::AddIPAddressObserver(this); |
| 200 } | 200 } |
| 201 | 201 |
| 202 ClientSocketPoolBaseHelper::~ClientSocketPoolBaseHelper() { | 202 ClientSocketPoolBaseHelper::~ClientSocketPoolBaseHelper() { |
| 203 // Clean up any idle sockets and pending connect jobs. Assert that we have no | 203 // Clean up any idle sockets and pending connect jobs. Assert that we have no |
| 204 // remaining active sockets or pending requests. They should have all been | 204 // remaining active sockets or pending requests. They should have all been |
| 205 // cleaned up prior to |this| being destroyed. | 205 // cleaned up prior to |this| being destroyed. |
| 206 Flush(); | 206 Flush(); |
| 207 DCHECK(group_map_.empty()); | 207 DCHECK(group_map_.empty()); |
| 208 DCHECK(pending_callback_map_.empty()); | 208 DCHECK(pending_callback_map_.empty()); |
| 209 DCHECK_EQ(0, connecting_socket_count_); | 209 DCHECK_EQ(0, connecting_socket_count_); |
| 210 DCHECK(higher_layer_pools_.empty()); | 210 DCHECK(higher_layer_pools_.empty()); |
| 211 | 211 |
| 212 NetworkChangeNotifier::RemoveIPAddressObserver(this); | 212 NetworkChangeNotifier::RemoveIPAddressObserver(this); |
| 213 } | 213 } |
| 214 | 214 |
| 215 ClientSocketPoolBaseHelper::CallbackResultPair::~CallbackResultPair() {} |
| 216 |
| 215 // InsertRequestIntoQueue inserts the request into the queue based on | 217 // InsertRequestIntoQueue inserts the request into the queue based on |
| 216 // priority. Highest priorities are closest to the front. Older requests are | 218 // priority. Highest priorities are closest to the front. Older requests are |
| 217 // prioritized over requests of equal priority. | 219 // prioritized over requests of equal priority. |
| 218 // | 220 // |
| 219 // static | 221 // static |
| 220 void ClientSocketPoolBaseHelper::InsertRequestIntoQueue( | 222 void ClientSocketPoolBaseHelper::InsertRequestIntoQueue( |
| 221 const Request* r, RequestQueue* pending_requests) { | 223 const Request* r, RequestQueue* pending_requests) { |
| 222 RequestQueue::iterator it = pending_requests->begin(); | 224 RequestQueue::iterator it = pending_requests->begin(); |
| 223 while (it != pending_requests->end() && r->priority() >= (*it)->priority()) | 225 while (it != pending_requests->end() && r->priority() >= (*it)->priority()) |
| 224 ++it; | 226 ++it; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 245 | 247 |
| 246 void ClientSocketPoolBaseHelper::RemoveLayeredPool(LayeredPool* pool) { | 248 void ClientSocketPoolBaseHelper::RemoveLayeredPool(LayeredPool* pool) { |
| 247 CHECK(pool); | 249 CHECK(pool); |
| 248 CHECK(ContainsKey(higher_layer_pools_, pool)); | 250 CHECK(ContainsKey(higher_layer_pools_, pool)); |
| 249 higher_layer_pools_.erase(pool); | 251 higher_layer_pools_.erase(pool); |
| 250 } | 252 } |
| 251 | 253 |
| 252 int ClientSocketPoolBaseHelper::RequestSocket( | 254 int ClientSocketPoolBaseHelper::RequestSocket( |
| 253 const std::string& group_name, | 255 const std::string& group_name, |
| 254 const Request* request) { | 256 const Request* request) { |
| 255 CHECK(request->callback()); | 257 CHECK(!request->callback().is_null()); |
| 256 CHECK(request->handle()); | 258 CHECK(request->handle()); |
| 257 | 259 |
| 258 // Cleanup any timed-out idle sockets if no timer is used. | 260 // Cleanup any timed-out idle sockets if no timer is used. |
| 259 if (!use_cleanup_timer_) | 261 if (!use_cleanup_timer_) |
| 260 CleanupIdleSockets(false); | 262 CleanupIdleSockets(false); |
| 261 | 263 |
| 262 request->net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL, NULL); | 264 request->net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL, NULL); |
| 263 Group* group = GetOrCreateGroup(group_name); | 265 Group* group = GetOrCreateGroup(group_name); |
| 264 | 266 |
| 265 int rv = RequestSocketInternal(group_name, request); | 267 int rv = RequestSocketInternal(group_name, request); |
| 266 if (rv != ERR_IO_PENDING) { | 268 if (rv != ERR_IO_PENDING) { |
| 267 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); | 269 request->net_log().EndEventWithNetErrorCode(NetLog::TYPE_SOCKET_POOL, rv); |
| 268 CHECK(!request->handle()->is_initialized()); | 270 CHECK(!request->handle()->is_initialized()); |
| 269 delete request; | 271 delete request; |
| 270 } else { | 272 } else { |
| 271 InsertRequestIntoQueue(request, group->mutable_pending_requests()); | 273 InsertRequestIntoQueue(request, group->mutable_pending_requests()); |
| 272 } | 274 } |
| 273 return rv; | 275 return rv; |
| 274 } | 276 } |
| 275 | 277 |
| 276 void ClientSocketPoolBaseHelper::RequestSockets( | 278 void ClientSocketPoolBaseHelper::RequestSockets( |
| 277 const std::string& group_name, | 279 const std::string& group_name, |
| 278 const Request& request, | 280 const Request& request, |
| 279 int num_sockets) { | 281 int num_sockets) { |
| 280 DCHECK(!request.callback()); | 282 DCHECK(request.callback().is_null()); |
| 281 DCHECK(!request.handle()); | 283 DCHECK(!request.handle()); |
| 282 | 284 |
| 283 // Cleanup any timed out idle sockets if no timer is used. | 285 // Cleanup any timed out idle sockets if no timer is used. |
| 284 if (!use_cleanup_timer_) | 286 if (!use_cleanup_timer_) |
| 285 CleanupIdleSockets(false); | 287 CleanupIdleSockets(false); |
| 286 | 288 |
| 287 if (num_sockets > max_sockets_per_group_) { | 289 if (num_sockets > max_sockets_per_group_) { |
| 288 num_sockets = max_sockets_per_group_; | 290 num_sockets = max_sockets_per_group_; |
| 289 } | 291 } |
| 290 | 292 |
| (...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1103 // Query the higher layers. | 1105 // Query the higher layers. |
| 1104 for (std::set<LayeredPool*>::const_iterator it = higher_layer_pools_.begin(); | 1106 for (std::set<LayeredPool*>::const_iterator it = higher_layer_pools_.begin(); |
| 1105 it != higher_layer_pools_.end(); ++it) { | 1107 it != higher_layer_pools_.end(); ++it) { |
| 1106 if ((*it)->CloseOneIdleConnection()) | 1108 if ((*it)->CloseOneIdleConnection()) |
| 1107 return true; | 1109 return true; |
| 1108 } | 1110 } |
| 1109 return false; | 1111 return false; |
| 1110 } | 1112 } |
| 1111 | 1113 |
| 1112 void ClientSocketPoolBaseHelper::InvokeUserCallbackLater( | 1114 void ClientSocketPoolBaseHelper::InvokeUserCallbackLater( |
| 1113 ClientSocketHandle* handle, OldCompletionCallback* callback, int rv) { | 1115 ClientSocketHandle* handle, const CompletionCallback& callback, int rv) { |
| 1114 CHECK(!ContainsKey(pending_callback_map_, handle)); | 1116 CHECK(!ContainsKey(pending_callback_map_, handle)); |
| 1115 pending_callback_map_[handle] = CallbackResultPair(callback, rv); | 1117 pending_callback_map_[handle] = CallbackResultPair(callback, rv); |
| 1116 MessageLoop::current()->PostTask( | 1118 MessageLoop::current()->PostTask( |
| 1117 FROM_HERE, | 1119 FROM_HERE, |
| 1118 method_factory_.NewRunnableMethod( | 1120 base::Bind(&ClientSocketPoolBaseHelper::InvokeUserCallback, |
| 1119 &ClientSocketPoolBaseHelper::InvokeUserCallback, | 1121 weak_factory_.GetWeakPtr(), handle)); |
| 1120 handle)); | |
| 1121 } | 1122 } |
| 1122 | 1123 |
| 1123 void ClientSocketPoolBaseHelper::InvokeUserCallback( | 1124 void ClientSocketPoolBaseHelper::InvokeUserCallback( |
| 1124 ClientSocketHandle* handle) { | 1125 ClientSocketHandle* handle) { |
| 1125 PendingCallbackMap::iterator it = pending_callback_map_.find(handle); | 1126 PendingCallbackMap::iterator it = pending_callback_map_.find(handle); |
| 1126 | 1127 |
| 1127 // Exit if the request has already been cancelled. | 1128 // Exit if the request has already been cancelled. |
| 1128 if (it == pending_callback_map_.end()) | 1129 if (it == pending_callback_map_.end()) |
| 1129 return; | 1130 return; |
| 1130 | 1131 |
| 1131 CHECK(!handle->is_initialized()); | 1132 CHECK(!handle->is_initialized()); |
| 1132 OldCompletionCallback* callback = it->second.callback; | 1133 CompletionCallback callback = it->second.callback; |
| 1133 int result = it->second.result; | 1134 int result = it->second.result; |
| 1134 pending_callback_map_.erase(it); | 1135 pending_callback_map_.erase(it); |
| 1135 callback->Run(result); | 1136 callback.Run(result); |
| 1136 } | 1137 } |
| 1137 | 1138 |
| 1138 ClientSocketPoolBaseHelper::Group::Group() | 1139 ClientSocketPoolBaseHelper::Group::Group() |
| 1139 : active_socket_count_(0), | 1140 : active_socket_count_(0), |
| 1140 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {} | 1141 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {} |
| 1141 | 1142 |
| 1142 ClientSocketPoolBaseHelper::Group::~Group() { | 1143 ClientSocketPoolBaseHelper::Group::~Group() { |
| 1143 CleanupBackupJob(); | 1144 CleanupBackupJob(); |
| 1144 } | 1145 } |
| 1145 | 1146 |
| 1146 void ClientSocketPoolBaseHelper::Group::StartBackupSocketTimer( | 1147 void ClientSocketPoolBaseHelper::Group::StartBackupSocketTimer( |
| 1147 const std::string& group_name, | 1148 const std::string& group_name, |
| 1148 ClientSocketPoolBaseHelper* pool) { | 1149 ClientSocketPoolBaseHelper* pool) { |
| 1149 // Only allow one timer pending to create a backup socket. | 1150 // Only allow one timer pending to create a backup socket. |
| 1150 if (!method_factory_.empty()) | 1151 if (weak_factory_.HasWeakPtrs()) |
| 1151 return; | 1152 return; |
| 1152 | 1153 |
| 1153 MessageLoop::current()->PostDelayedTask( | 1154 MessageLoop::current()->PostDelayedTask( |
| 1154 FROM_HERE, | 1155 FROM_HERE, |
| 1155 method_factory_.NewRunnableMethod( | 1156 base::Bind(&Group::OnBackupSocketTimerFired, weak_factory_.GetWeakPtr(), |
| 1156 &Group::OnBackupSocketTimerFired, group_name, pool), | 1157 group_name, pool), |
| 1157 pool->ConnectRetryIntervalMs()); | 1158 pool->ConnectRetryIntervalMs()); |
| 1158 } | 1159 } |
| 1159 | 1160 |
| 1160 bool ClientSocketPoolBaseHelper::Group::TryToUsePreconnectConnectJob() { | 1161 bool ClientSocketPoolBaseHelper::Group::TryToUsePreconnectConnectJob() { |
| 1161 for (std::set<ConnectJob*>::iterator it = jobs_.begin(); | 1162 for (std::set<ConnectJob*>::iterator it = jobs_.begin(); |
| 1162 it != jobs_.end(); ++it) { | 1163 it != jobs_.end(); ++it) { |
| 1163 ConnectJob* job = *it; | 1164 ConnectJob* job = *it; |
| 1164 if (job->is_unused_preconnect()) { | 1165 if (job->is_unused_preconnect()) { |
| 1165 job->UseForNormalRequest(); | 1166 job->UseForNormalRequest(); |
| 1166 return true; | 1167 return true; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1200 AddJob(backup_job); | 1201 AddJob(backup_job); |
| 1201 if (rv != ERR_IO_PENDING) | 1202 if (rv != ERR_IO_PENDING) |
| 1202 pool->OnConnectJobComplete(rv, backup_job); | 1203 pool->OnConnectJobComplete(rv, backup_job); |
| 1203 } | 1204 } |
| 1204 | 1205 |
| 1205 void ClientSocketPoolBaseHelper::Group::RemoveAllJobs() { | 1206 void ClientSocketPoolBaseHelper::Group::RemoveAllJobs() { |
| 1206 // Delete active jobs. | 1207 // Delete active jobs. |
| 1207 STLDeleteElements(&jobs_); | 1208 STLDeleteElements(&jobs_); |
| 1208 | 1209 |
| 1209 // Cancel pending backup job. | 1210 // Cancel pending backup job. |
| 1210 method_factory_.RevokeAll(); | 1211 weak_factory_.InvalidateWeakPtrs(); |
| 1211 } | 1212 } |
| 1212 | 1213 |
| 1213 } // namespace internal | 1214 } // namespace internal |
| 1214 | 1215 |
| 1215 } // namespace net | 1216 } // namespace net |
| OLD | NEW |