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) { |
| 976 using ::std::tr1::bind; |
| 977 using ::std::tr1::function; |
| 978 |
979 CHECK(!ContainsKey(pending_callback_map_, handle)); | 979 CHECK(!ContainsKey(pending_callback_map_, handle)); |
980 pending_callback_map_[handle] = CallbackResultPair(callback, rv); | 980 pending_callback_map_[handle] = CallbackResultPair(callback, rv); |
981 MessageLoop::current()->PostTask( | 981 |
982 FROM_HERE, | 982 function<void(void)> invoke_thunk = |
983 method_factory_.NewRunnableMethod( | 983 bind(&ClientSocketPoolBaseHelper::InvokeUserCallback, this, handle); |
984 &ClientSocketPoolBaseHelper::InvokeUserCallback, | 984 MessageLoop::current()->PostClosure(FROM_HERE, |
985 handle)); | 985 closure_canceller_.Wrap(invoke_thunk)); |
986 } | 986 } |
987 | 987 |
988 void ClientSocketPoolBaseHelper::InvokeUserCallback( | 988 void ClientSocketPoolBaseHelper::InvokeUserCallback( |
989 ClientSocketHandle* handle) { | 989 ClientSocketHandle* handle) { |
990 PendingCallbackMap::iterator it = pending_callback_map_.find(handle); | 990 PendingCallbackMap::iterator it = pending_callback_map_.find(handle); |
991 | 991 |
992 // Exit if the request has already been cancelled. | 992 // Exit if the request has already been cancelled. |
993 if (it == pending_callback_map_.end()) | 993 if (it == pending_callback_map_.end()) |
994 return; | 994 return; |
995 | 995 |
996 CHECK(!handle->is_initialized()); | 996 CHECK(!handle->is_initialized()); |
997 CompletionCallback* callback = it->second.callback; | 997 Tr1CompletionCallback callback = it->second.callback; |
998 int result = it->second.result; | 998 int result = it->second.result; |
999 pending_callback_map_.erase(it); | 999 pending_callback_map_.erase(it); |
1000 callback->Run(result); | 1000 callback(result); |
1001 } | 1001 } |
1002 | 1002 |
1003 ClientSocketPoolBaseHelper::Group::Group() | 1003 ClientSocketPoolBaseHelper::Group::Group() |
1004 : active_socket_count_(0), | 1004 : active_socket_count_(0) {} |
1005 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {} | |
1006 | 1005 |
1007 ClientSocketPoolBaseHelper::Group::~Group() { | 1006 ClientSocketPoolBaseHelper::Group::~Group() { |
1008 CleanupBackupJob(); | 1007 CleanupBackupJob(); |
1009 } | 1008 } |
1010 | 1009 |
1011 void ClientSocketPoolBaseHelper::Group::StartBackupSocketTimer( | 1010 void ClientSocketPoolBaseHelper::Group::StartBackupSocketTimer( |
1012 const std::string& group_name, | 1011 const std::string& group_name, |
1013 ClientSocketPoolBaseHelper* pool) { | 1012 ClientSocketPoolBaseHelper* pool) { |
| 1013 using ::std::tr1::bind; |
| 1014 using ::std::tr1::function; |
| 1015 |
1014 // Only allow one timer pending to create a backup socket. | 1016 // Only allow one timer pending to create a backup socket. |
1015 if (!method_factory_.empty()) | 1017 if (!closure_canceller_.empty()) |
1016 return; | 1018 return; |
1017 | 1019 |
1018 MessageLoop::current()->PostDelayedTask( | 1020 // TODO(ajwong): Somethings wrong with inlining this call as opposed to |
| 1021 // breaking out a separate variable. Figure out syntax issue. It's probably |
| 1022 // the template in ClosureCanceller::Wrap. |
| 1023 function<void(void)> invoke_thunk = |
| 1024 bind(&Group::OnBackupSocketTimerFired, this, group_name, pool); |
| 1025 |
| 1026 MessageLoop::current()->PostDelayedClosure( |
1019 FROM_HERE, | 1027 FROM_HERE, |
1020 method_factory_.NewRunnableMethod( | 1028 closure_canceller_.Wrap(invoke_thunk), |
1021 &Group::OnBackupSocketTimerFired, group_name, pool), | |
1022 pool->ConnectRetryIntervalMs()); | 1029 pool->ConnectRetryIntervalMs()); |
1023 } | 1030 } |
1024 | 1031 |
1025 bool ClientSocketPoolBaseHelper::Group::TryToUsePreconnectConnectJob() { | 1032 bool ClientSocketPoolBaseHelper::Group::TryToUsePreconnectConnectJob() { |
1026 for (std::set<ConnectJob*>::iterator it = jobs_.begin(); | 1033 for (std::set<ConnectJob*>::iterator it = jobs_.begin(); |
1027 it != jobs_.end(); ++it) { | 1034 it != jobs_.end(); ++it) { |
1028 ConnectJob* job = *it; | 1035 ConnectJob* job = *it; |
1029 if (job->is_unused_preconnect()) { | 1036 if (job->is_unused_preconnect()) { |
1030 job->UseForNormalRequest(); | 1037 job->UseForNormalRequest(); |
1031 return true; | 1038 return true; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1067 AddJob(backup_job); | 1074 AddJob(backup_job); |
1068 if (rv != ERR_IO_PENDING) | 1075 if (rv != ERR_IO_PENDING) |
1069 pool->OnConnectJobComplete(rv, backup_job); | 1076 pool->OnConnectJobComplete(rv, backup_job); |
1070 } | 1077 } |
1071 | 1078 |
1072 void ClientSocketPoolBaseHelper::Group::RemoveAllJobs() { | 1079 void ClientSocketPoolBaseHelper::Group::RemoveAllJobs() { |
1073 // Delete active jobs. | 1080 // Delete active jobs. |
1074 STLDeleteElements(&jobs_); | 1081 STLDeleteElements(&jobs_); |
1075 | 1082 |
1076 // Cancel pending backup job. | 1083 // Cancel pending backup job. |
1077 method_factory_.RevokeAll(); | 1084 closure_canceller_.RevokeAll(); |
1078 } | 1085 } |
1079 | 1086 |
1080 } // namespace internal | 1087 } // namespace internal |
1081 | 1088 |
1082 } // namespace net | 1089 } // namespace net |
OLD | NEW |