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/tcp_client_socket_pool.h" | 5 #include "net/socket/tcp_client_socket_pool.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
11 #include "base/time.h" | 11 #include "base/time.h" |
12 #include "net/base/load_log.h" | 12 #include "net/base/net_log.h" |
13 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
14 #include "net/socket/client_socket_factory.h" | 14 #include "net/socket/client_socket_factory.h" |
15 #include "net/socket/client_socket_handle.h" | 15 #include "net/socket/client_socket_handle.h" |
16 #include "net/socket/client_socket_pool_base.h" | 16 #include "net/socket/client_socket_pool_base.h" |
17 #include "net/socket/tcp_client_socket.h" | 17 #include "net/socket/tcp_client_socket.h" |
18 | 18 |
19 using base::TimeDelta; | 19 using base::TimeDelta; |
20 | 20 |
21 namespace net { | 21 namespace net { |
22 | 22 |
23 // TCPConnectJobs will time out after this many seconds. Note this is the total | 23 // TCPConnectJobs will time out after this many seconds. Note this is the total |
24 // time, including both host resolution and TCP connect() times. | 24 // time, including both host resolution and TCP connect() times. |
25 // | 25 // |
26 // TODO(eroman): The use of this constant needs to be re-evaluated. The time | 26 // TODO(eroman): The use of this constant needs to be re-evaluated. The time |
27 // needed for TCPClientSocketXXX::Connect() can be arbitrarily long, since | 27 // needed for TCPClientSocketXXX::Connect() can be arbitrarily long, since |
28 // the address list may contain many alternatives, and most of those may | 28 // the address list may contain many alternatives, and most of those may |
29 // timeout. Even worse, the per-connect timeout threshold varies greatly | 29 // timeout. Even worse, the per-connect timeout threshold varies greatly |
30 // between systems (anywhere from 20 seconds to 190 seconds). | 30 // between systems (anywhere from 20 seconds to 190 seconds). |
31 // See comment #12 at http://crbug.com/23364 for specifics. | 31 // See comment #12 at http://crbug.com/23364 for specifics. |
32 static const int kTCPConnectJobTimeoutInSeconds = 240; // 4 minutes. | 32 static const int kTCPConnectJobTimeoutInSeconds = 240; // 4 minutes. |
33 | 33 |
34 TCPConnectJob::TCPConnectJob( | 34 TCPConnectJob::TCPConnectJob( |
35 const std::string& group_name, | 35 const std::string& group_name, |
36 const TCPSocketParams& params, | 36 const TCPSocketParams& params, |
37 base::TimeDelta timeout_duration, | 37 base::TimeDelta timeout_duration, |
38 ClientSocketFactory* client_socket_factory, | 38 ClientSocketFactory* client_socket_factory, |
39 HostResolver* host_resolver, | 39 HostResolver* host_resolver, |
40 Delegate* delegate, | 40 Delegate* delegate, |
41 LoadLog* load_log) | 41 const BoundNetLog& net_log) |
42 : ConnectJob(group_name, timeout_duration, delegate, load_log), | 42 : ConnectJob(group_name, timeout_duration, delegate, net_log), |
43 params_(params), | 43 params_(params), |
44 client_socket_factory_(client_socket_factory), | 44 client_socket_factory_(client_socket_factory), |
45 ALLOW_THIS_IN_INITIALIZER_LIST( | 45 ALLOW_THIS_IN_INITIALIZER_LIST( |
46 callback_(this, | 46 callback_(this, |
47 &TCPConnectJob::OnIOComplete)), | 47 &TCPConnectJob::OnIOComplete)), |
48 resolver_(host_resolver) {} | 48 resolver_(host_resolver) {} |
49 | 49 |
50 TCPConnectJob::~TCPConnectJob() { | 50 TCPConnectJob::~TCPConnectJob() { |
51 // We don't worry about cancelling the host resolution and TCP connect, since | 51 // We don't worry about cancelling the host resolution and TCP connect, since |
52 // ~SingleRequestHostResolver and ~ClientSocket will take care of it. | 52 // ~SingleRequestHostResolver and ~ClientSocket will take care of it. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 break; | 106 break; |
107 } | 107 } |
108 } while (rv != ERR_IO_PENDING && next_state_ != kStateNone); | 108 } while (rv != ERR_IO_PENDING && next_state_ != kStateNone); |
109 | 109 |
110 return rv; | 110 return rv; |
111 } | 111 } |
112 | 112 |
113 int TCPConnectJob::DoResolveHost() { | 113 int TCPConnectJob::DoResolveHost() { |
114 next_state_ = kStateResolveHostComplete; | 114 next_state_ = kStateResolveHostComplete; |
115 return resolver_.Resolve(params_.destination(), &addresses_, &callback_, | 115 return resolver_.Resolve(params_.destination(), &addresses_, &callback_, |
116 load_log()); | 116 net_log()); |
117 } | 117 } |
118 | 118 |
119 int TCPConnectJob::DoResolveHostComplete(int result) { | 119 int TCPConnectJob::DoResolveHostComplete(int result) { |
120 if (result == OK) | 120 if (result == OK) |
121 next_state_ = kStateTCPConnect; | 121 next_state_ = kStateTCPConnect; |
122 return result; | 122 return result; |
123 } | 123 } |
124 | 124 |
125 int TCPConnectJob::DoTCPConnect() { | 125 int TCPConnectJob::DoTCPConnect() { |
126 next_state_ = kStateTCPConnectComplete; | 126 next_state_ = kStateTCPConnectComplete; |
127 set_socket(client_socket_factory_->CreateTCPClientSocket(addresses_)); | 127 set_socket(client_socket_factory_->CreateTCPClientSocket(addresses_)); |
128 connect_start_time_ = base::TimeTicks::Now(); | 128 connect_start_time_ = base::TimeTicks::Now(); |
129 return socket()->Connect(&callback_, load_log()); | 129 return socket()->Connect(&callback_, net_log()); |
130 } | 130 } |
131 | 131 |
132 int TCPConnectJob::DoTCPConnectComplete(int result) { | 132 int TCPConnectJob::DoTCPConnectComplete(int result) { |
133 if (result == OK) { | 133 if (result == OK) { |
134 DCHECK(connect_start_time_ != base::TimeTicks()); | 134 DCHECK(connect_start_time_ != base::TimeTicks()); |
135 DCHECK(start_time_ != base::TimeTicks()); | 135 DCHECK(start_time_ != base::TimeTicks()); |
136 base::TimeTicks now = base::TimeTicks::Now(); | 136 base::TimeTicks now = base::TimeTicks::Now(); |
137 base::TimeDelta total_duration = now - start_time_; | 137 base::TimeDelta total_duration = now - start_time_; |
138 UMA_HISTOGRAM_CUSTOM_TIMES( | 138 UMA_HISTOGRAM_CUSTOM_TIMES( |
139 "Net.DNS_Resolution_And_TCP_Connection_Latency2", | 139 "Net.DNS_Resolution_And_TCP_Connection_Latency2", |
(...skipping 13 matching lines...) Expand all Loading... |
153 set_socket(NULL); | 153 set_socket(NULL); |
154 } | 154 } |
155 | 155 |
156 return result; | 156 return result; |
157 } | 157 } |
158 | 158 |
159 ConnectJob* TCPClientSocketPool::TCPConnectJobFactory::NewConnectJob( | 159 ConnectJob* TCPClientSocketPool::TCPConnectJobFactory::NewConnectJob( |
160 const std::string& group_name, | 160 const std::string& group_name, |
161 const PoolBase::Request& request, | 161 const PoolBase::Request& request, |
162 ConnectJob::Delegate* delegate, | 162 ConnectJob::Delegate* delegate, |
163 LoadLog* load_log) const { | 163 const BoundNetLog& net_log) const { |
164 return new TCPConnectJob( | 164 return new TCPConnectJob( |
165 group_name, request.params(), | 165 group_name, request.params(), |
166 base::TimeDelta::FromSeconds(kTCPConnectJobTimeoutInSeconds), | 166 base::TimeDelta::FromSeconds(kTCPConnectJobTimeoutInSeconds), |
167 client_socket_factory_, host_resolver_, delegate, load_log); | 167 client_socket_factory_, host_resolver_, delegate, net_log); |
168 } | 168 } |
169 | 169 |
170 TCPClientSocketPool::TCPClientSocketPool( | 170 TCPClientSocketPool::TCPClientSocketPool( |
171 int max_sockets, | 171 int max_sockets, |
172 int max_sockets_per_group, | 172 int max_sockets_per_group, |
173 HostResolver* host_resolver, | 173 HostResolver* host_resolver, |
174 ClientSocketFactory* client_socket_factory, | 174 ClientSocketFactory* client_socket_factory, |
175 NetworkChangeNotifier* network_change_notifier) | 175 NetworkChangeNotifier* network_change_notifier) |
176 : base_(max_sockets, max_sockets_per_group, | 176 : base_(max_sockets, max_sockets_per_group, |
177 base::TimeDelta::FromSeconds(kUnusedIdleSocketTimeout), | 177 base::TimeDelta::FromSeconds(kUnusedIdleSocketTimeout), |
178 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout), | 178 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout), |
179 new TCPConnectJobFactory(client_socket_factory, host_resolver), | 179 new TCPConnectJobFactory(client_socket_factory, host_resolver), |
180 network_change_notifier) {} | 180 network_change_notifier) {} |
181 | 181 |
182 TCPClientSocketPool::~TCPClientSocketPool() {} | 182 TCPClientSocketPool::~TCPClientSocketPool() {} |
183 | 183 |
184 int TCPClientSocketPool::RequestSocket( | 184 int TCPClientSocketPool::RequestSocket( |
185 const std::string& group_name, | 185 const std::string& group_name, |
186 const void* params, | 186 const void* params, |
187 RequestPriority priority, | 187 RequestPriority priority, |
188 ClientSocketHandle* handle, | 188 ClientSocketHandle* handle, |
189 CompletionCallback* callback, | 189 CompletionCallback* callback, |
190 LoadLog* load_log) { | 190 const BoundNetLog& net_log) { |
191 const TCPSocketParams* casted_params = | 191 const TCPSocketParams* casted_params = |
192 static_cast<const TCPSocketParams*>(params); | 192 static_cast<const TCPSocketParams*>(params); |
193 | 193 |
194 if (LoadLog::IsUnbounded(load_log)) { | 194 if (net_log.HasListener()) { |
195 LoadLog::AddString( | 195 net_log.AddString(StringPrintf("Requested TCP socket to: %s [port %d]", |
196 load_log, | 196 casted_params->destination().hostname().c_str(), |
197 StringPrintf("Requested TCP socket to: %s [port %d]", | 197 casted_params->destination().port())); |
198 casted_params->destination().hostname().c_str(), | |
199 casted_params->destination().port())); | |
200 } | 198 } |
201 | 199 |
202 return base_.RequestSocket(group_name, *casted_params, priority, handle, | 200 return base_.RequestSocket(group_name, *casted_params, priority, handle, |
203 callback, load_log); | 201 callback, net_log); |
204 } | 202 } |
205 | 203 |
206 void TCPClientSocketPool::CancelRequest( | 204 void TCPClientSocketPool::CancelRequest( |
207 const std::string& group_name, | 205 const std::string& group_name, |
208 const ClientSocketHandle* handle) { | 206 const ClientSocketHandle* handle) { |
209 base_.CancelRequest(group_name, handle); | 207 base_.CancelRequest(group_name, handle); |
210 } | 208 } |
211 | 209 |
212 void TCPClientSocketPool::ReleaseSocket( | 210 void TCPClientSocketPool::ReleaseSocket( |
213 const std::string& group_name, | 211 const std::string& group_name, |
214 ClientSocket* socket) { | 212 ClientSocket* socket) { |
215 base_.ReleaseSocket(group_name, socket); | 213 base_.ReleaseSocket(group_name, socket); |
216 } | 214 } |
217 | 215 |
218 void TCPClientSocketPool::CloseIdleSockets() { | 216 void TCPClientSocketPool::CloseIdleSockets() { |
219 base_.CloseIdleSockets(); | 217 base_.CloseIdleSockets(); |
220 } | 218 } |
221 | 219 |
222 int TCPClientSocketPool::IdleSocketCountInGroup( | 220 int TCPClientSocketPool::IdleSocketCountInGroup( |
223 const std::string& group_name) const { | 221 const std::string& group_name) const { |
224 return base_.IdleSocketCountInGroup(group_name); | 222 return base_.IdleSocketCountInGroup(group_name); |
225 } | 223 } |
226 | 224 |
227 LoadState TCPClientSocketPool::GetLoadState( | 225 LoadState TCPClientSocketPool::GetLoadState( |
228 const std::string& group_name, const ClientSocketHandle* handle) const { | 226 const std::string& group_name, const ClientSocketHandle* handle) const { |
229 return base_.GetLoadState(group_name, handle); | 227 return base_.GetLoadState(group_name, handle); |
230 } | 228 } |
231 | 229 |
232 } // namespace net | 230 } // namespace net |
OLD | NEW |