| 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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 | 126 |
| 127 net_log_.AddEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT, NULL); | 127 net_log_.AddEvent(NetLog::TYPE_SOCKET_POOL_CONNECT_JOB_TIMED_OUT, NULL); |
| 128 | 128 |
| 129 NotifyDelegateOfCompletion(ERR_TIMED_OUT); | 129 NotifyDelegateOfCompletion(ERR_TIMED_OUT); |
| 130 } | 130 } |
| 131 | 131 |
| 132 namespace internal { | 132 namespace internal { |
| 133 | 133 |
| 134 ClientSocketPoolBaseHelper::Request::Request( | 134 ClientSocketPoolBaseHelper::Request::Request( |
| 135 ClientSocketHandle* handle, | 135 ClientSocketHandle* handle, |
| 136 CompletionCallback* callback, | 136 Tr1CompletionCallback callback, |
| 137 RequestPriority priority, | 137 RequestPriority priority, |
| 138 Flags flags, | 138 Flags flags, |
| 139 const BoundNetLog& net_log) | 139 const BoundNetLog& net_log) |
| 140 : handle_(handle), | 140 : handle_(handle), |
| 141 callback_(callback), | 141 callback_(callback), |
| 142 priority_(priority), | 142 priority_(priority), |
| 143 flags_(flags), | 143 flags_(flags), |
| 144 net_log_(net_log) {} | 144 net_log_(net_log) {} |
| 145 | 145 |
| 146 ClientSocketPoolBaseHelper::Request::~Request() {} | 146 ClientSocketPoolBaseHelper::Request::~Request() {} |
| 147 | 147 |
| 148 ClientSocketPoolBaseHelper::ClientSocketPoolBaseHelper( | 148 ClientSocketPoolBaseHelper::ClientSocketPoolBaseHelper( |
| 149 int max_sockets, | 149 int max_sockets, |
| 150 int max_sockets_per_group, | 150 int max_sockets_per_group, |
| 151 base::TimeDelta unused_idle_socket_timeout, | 151 base::TimeDelta unused_idle_socket_timeout, |
| 152 base::TimeDelta used_idle_socket_timeout, | 152 base::TimeDelta used_idle_socket_timeout, |
| 153 ConnectJobFactory* connect_job_factory) | 153 ConnectJobFactory* connect_job_factory) |
| 154 : idle_socket_count_(0), | 154 : idle_socket_count_(0), |
| 155 connecting_socket_count_(0), | 155 connecting_socket_count_(0), |
| 156 handed_out_socket_count_(0), | 156 handed_out_socket_count_(0), |
| 157 max_sockets_(max_sockets), | 157 max_sockets_(max_sockets), |
| 158 max_sockets_per_group_(max_sockets_per_group), | 158 max_sockets_per_group_(max_sockets_per_group), |
| 159 unused_idle_socket_timeout_(unused_idle_socket_timeout), | 159 unused_idle_socket_timeout_(unused_idle_socket_timeout), |
| 160 used_idle_socket_timeout_(used_idle_socket_timeout), | 160 used_idle_socket_timeout_(used_idle_socket_timeout), |
| 161 connect_job_factory_(connect_job_factory), | 161 connect_job_factory_(connect_job_factory), |
| 162 connect_backup_jobs_enabled_(false), | 162 connect_backup_jobs_enabled_(false), |
| 163 pool_generation_number_(0), | 163 pool_generation_number_(0) { |
| 164 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | |
| 165 DCHECK_LE(0, max_sockets_per_group); | 164 DCHECK_LE(0, max_sockets_per_group); |
| 166 DCHECK_LE(max_sockets_per_group, max_sockets); | 165 DCHECK_LE(max_sockets_per_group, max_sockets); |
| 167 | 166 |
| 168 NetworkChangeNotifier::AddObserver(this); | 167 NetworkChangeNotifier::AddObserver(this); |
| 169 } | 168 } |
| 170 | 169 |
| 171 ClientSocketPoolBaseHelper::~ClientSocketPoolBaseHelper() { | 170 ClientSocketPoolBaseHelper::~ClientSocketPoolBaseHelper() { |
| 172 // Clean up any idle sockets and pending connect jobs. Assert that we have no | 171 // Clean up any idle sockets and pending connect jobs. Assert that we have no |
| 173 // remaining active sockets or pending requests. They should have all been | 172 // remaining active sockets or pending requests. They should have all been |
| 174 // cleaned up prior to |this| being destroyed. | 173 // cleaned up prior to |this| being destroyed. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 201 group->mutable_pending_requests()->erase(it); | 200 group->mutable_pending_requests()->erase(it); |
| 202 // If there are no more requests, we kill the backup timer. | 201 // If there are no more requests, we kill the backup timer. |
| 203 if (group->pending_requests().empty()) | 202 if (group->pending_requests().empty()) |
| 204 group->CleanupBackupJob(); | 203 group->CleanupBackupJob(); |
| 205 return req; | 204 return req; |
| 206 } | 205 } |
| 207 | 206 |
| 208 int ClientSocketPoolBaseHelper::RequestSocket( | 207 int ClientSocketPoolBaseHelper::RequestSocket( |
| 209 const std::string& group_name, | 208 const std::string& group_name, |
| 210 const Request* request) { | 209 const Request* request) { |
| 211 CHECK(request->callback()); | |
| 212 CHECK(request->handle()); | 210 CHECK(request->handle()); |
| 213 | 211 |
| 214 request->net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL, NULL); | 212 request->net_log().BeginEvent(NetLog::TYPE_SOCKET_POOL, NULL); |
| 215 Group* group = GetOrCreateGroup(group_name); | 213 Group* group = GetOrCreateGroup(group_name); |
| 216 | 214 |
| 217 int rv = RequestSocketInternal(group_name, request); | 215 int rv = RequestSocketInternal(group_name, request); |
| 218 if (rv != ERR_IO_PENDING) { | 216 if (rv != ERR_IO_PENDING) { |
| 219 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL); | 217 request->net_log().EndEvent(NetLog::TYPE_SOCKET_POOL, NULL); |
| 220 CHECK(!request->handle()->is_initialized()); | 218 CHECK(!request->handle()->is_initialized()); |
| 221 delete request; | 219 delete request; |
| 222 } else { | 220 } else { |
| 223 InsertRequestIntoQueue(request, group->mutable_pending_requests()); | 221 InsertRequestIntoQueue(request, group->mutable_pending_requests()); |
| 224 } | 222 } |
| 225 return rv; | 223 return rv; |
| 226 } | 224 } |
| 227 | 225 |
| 228 void ClientSocketPoolBaseHelper::RequestSockets( | 226 void ClientSocketPoolBaseHelper::RequestSockets( |
| 229 const std::string& group_name, | 227 const std::string& group_name, |
| 230 const Request& request, | 228 const Request& request, |
| 231 int num_sockets) { | 229 int num_sockets) { |
| 232 DCHECK(!request.callback()); | |
| 233 DCHECK(!request.handle()); | 230 DCHECK(!request.handle()); |
| 234 | 231 |
| 235 if (num_sockets > max_sockets_per_group_) { | 232 if (num_sockets > max_sockets_per_group_) { |
| 236 num_sockets = max_sockets_per_group_; | 233 num_sockets = max_sockets_per_group_; |
| 237 } | 234 } |
| 238 | 235 |
| 239 request.net_log().BeginEvent( | 236 request.net_log().BeginEvent( |
| 240 NetLog::TYPE_SOCKET_POOL_CONNECTING_N_SOCKETS, | 237 NetLog::TYPE_SOCKET_POOL_CONNECTING_N_SOCKETS, |
| 241 make_scoped_refptr(new NetLogIntegerParameter( | 238 make_scoped_refptr(new NetLogIntegerParameter( |
| 242 "num_sockets", num_sockets))); | 239 "num_sockets", num_sockets))); |
| (...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 968 } | 965 } |
| 969 } | 966 } |
| 970 | 967 |
| 971 if (!exception_group) | 968 if (!exception_group) |
| 972 LOG(DFATAL) << "No idle socket found to close!."; | 969 LOG(DFATAL) << "No idle socket found to close!."; |
| 973 | 970 |
| 974 return false; | 971 return false; |
| 975 } | 972 } |
| 976 | 973 |
| 977 void ClientSocketPoolBaseHelper::InvokeUserCallbackLater( | 974 void ClientSocketPoolBaseHelper::InvokeUserCallbackLater( |
| 978 ClientSocketHandle* handle, CompletionCallback* callback, int rv) { | 975 ClientSocketHandle* handle, Tr1CompletionCallback callback, int rv) { |
| 979 CHECK(!ContainsKey(pending_callback_map_, handle)); | 976 CHECK(!ContainsKey(pending_callback_map_, handle)); |
| 980 pending_callback_map_[handle] = CallbackResultPair(callback, rv); | 977 pending_callback_map_[handle] = CallbackResultPair(callback, rv); |
| 981 MessageLoop::current()->PostTask( | 978 |
| 982 FROM_HERE, | 979 base::Thunk<void(void)> invoke_thunk = |
| 983 method_factory_.NewRunnableMethod( | 980 base::Prebind(&ClientSocketPoolBaseHelper::InvokeUserCallback, |
| 984 &ClientSocketPoolBaseHelper::InvokeUserCallback, | 981 base::Unretained(this), handle); |
| 985 handle)); | 982 MessageLoop::current()->PostClosure(FROM_HERE, |
| 983 thunk_canceller_.Wrap(invoke_thunk)); |
| 986 } | 984 } |
| 987 | 985 |
| 988 void ClientSocketPoolBaseHelper::InvokeUserCallback( | 986 void ClientSocketPoolBaseHelper::InvokeUserCallback( |
| 989 ClientSocketHandle* handle) { | 987 ClientSocketHandle* handle) { |
| 990 PendingCallbackMap::iterator it = pending_callback_map_.find(handle); | 988 PendingCallbackMap::iterator it = pending_callback_map_.find(handle); |
| 991 | 989 |
| 992 // Exit if the request has already been cancelled. | 990 // Exit if the request has already been cancelled. |
| 993 if (it == pending_callback_map_.end()) | 991 if (it == pending_callback_map_.end()) |
| 994 return; | 992 return; |
| 995 | 993 |
| 996 CHECK(!handle->is_initialized()); | 994 CHECK(!handle->is_initialized()); |
| 997 CompletionCallback* callback = it->second.callback; | 995 Tr1CompletionCallback callback = it->second.callback; |
| 998 int result = it->second.result; | 996 int result = it->second.result; |
| 999 pending_callback_map_.erase(it); | 997 pending_callback_map_.erase(it); |
| 1000 callback->Run(result); | 998 callback(result); |
| 1001 } | 999 } |
| 1002 | 1000 |
| 1003 ClientSocketPoolBaseHelper::Group::Group() | 1001 ClientSocketPoolBaseHelper::Group::Group() |
| 1004 : active_socket_count_(0), | 1002 : active_socket_count_(0) {} |
| 1005 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {} | |
| 1006 | 1003 |
| 1007 ClientSocketPoolBaseHelper::Group::~Group() { | 1004 ClientSocketPoolBaseHelper::Group::~Group() { |
| 1008 CleanupBackupJob(); | 1005 CleanupBackupJob(); |
| 1009 } | 1006 } |
| 1010 | 1007 |
| 1011 void ClientSocketPoolBaseHelper::Group::StartBackupSocketTimer( | 1008 void ClientSocketPoolBaseHelper::Group::StartBackupSocketTimer( |
| 1012 const std::string& group_name, | 1009 const std::string& group_name, |
| 1013 ClientSocketPoolBaseHelper* pool) { | 1010 ClientSocketPoolBaseHelper* pool) { |
| 1014 // Only allow one timer pending to create a backup socket. | 1011 // Only allow one timer pending to create a backup socket. |
| 1015 if (!method_factory_.empty()) | 1012 if (!thunk_canceller_.empty()) |
| 1016 return; | 1013 return; |
| 1017 | 1014 |
| 1018 MessageLoop::current()->PostDelayedTask( | 1015 // TODO(ajwong): Somethings wrong with inlining this call as opposed to |
| 1016 // breaking out a separate variable. Figure out syntax issue. It's probably |
| 1017 // the template in ClosureCanceller::Wrap. |
| 1018 base::Thunk<void(void)> invoke_thunk = |
| 1019 base::Prebind(&Group::OnBackupSocketTimerFired, |
| 1020 base::Unretained(this), group_name, pool); |
| 1021 |
| 1022 MessageLoop::current()->PostDelayedClosure( |
| 1019 FROM_HERE, | 1023 FROM_HERE, |
| 1020 method_factory_.NewRunnableMethod( | 1024 thunk_canceller_.Wrap(invoke_thunk), |
| 1021 &Group::OnBackupSocketTimerFired, group_name, pool), | |
| 1022 pool->ConnectRetryIntervalMs()); | 1025 pool->ConnectRetryIntervalMs()); |
| 1023 } | 1026 } |
| 1024 | 1027 |
| 1025 bool ClientSocketPoolBaseHelper::Group::TryToUsePreconnectConnectJob() { | 1028 bool ClientSocketPoolBaseHelper::Group::TryToUsePreconnectConnectJob() { |
| 1026 for (std::set<ConnectJob*>::iterator it = jobs_.begin(); | 1029 for (std::set<ConnectJob*>::iterator it = jobs_.begin(); |
| 1027 it != jobs_.end(); ++it) { | 1030 it != jobs_.end(); ++it) { |
| 1028 ConnectJob* job = *it; | 1031 ConnectJob* job = *it; |
| 1029 if (job->is_unused_preconnect()) { | 1032 if (job->is_unused_preconnect()) { |
| 1030 job->UseForNormalRequest(); | 1033 job->UseForNormalRequest(); |
| 1031 return true; | 1034 return true; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1067 AddJob(backup_job); | 1070 AddJob(backup_job); |
| 1068 if (rv != ERR_IO_PENDING) | 1071 if (rv != ERR_IO_PENDING) |
| 1069 pool->OnConnectJobComplete(rv, backup_job); | 1072 pool->OnConnectJobComplete(rv, backup_job); |
| 1070 } | 1073 } |
| 1071 | 1074 |
| 1072 void ClientSocketPoolBaseHelper::Group::RemoveAllJobs() { | 1075 void ClientSocketPoolBaseHelper::Group::RemoveAllJobs() { |
| 1073 // Delete active jobs. | 1076 // Delete active jobs. |
| 1074 STLDeleteElements(&jobs_); | 1077 STLDeleteElements(&jobs_); |
| 1075 | 1078 |
| 1076 // Cancel pending backup job. | 1079 // Cancel pending backup job. |
| 1077 method_factory_.RevokeAll(); | 1080 thunk_canceller_.RevokeAll(); |
| 1078 } | 1081 } |
| 1079 | 1082 |
| 1080 } // namespace internal | 1083 } // namespace internal |
| 1081 | 1084 |
| 1082 } // namespace net | 1085 } // namespace net |
| OLD | NEW |