Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: net/socket/sctp_client_socket_pool.cc

Issue 6800009: Attn: Mike Belshe Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "net/socket/sctp_client_socket_pool.h"
6
7 #include "base/compiler_specific.h"
8 #include "base/logging.h"
9 #include "base/message_loop.h"
10 #include "base/metrics/histogram.h"
11 #include "base/string_util.h"
12 #include "base/time.h"
13 #include "net/base/net_log.h"
14 #include "net/base/net_errors.h"
15 #include "net/socket/client_socket_factory.h"
16 #include "net/socket/client_socket_handle.h"
17 #include "net/socket/client_socket_pool_base.h"
18 #include "net/socket/sctp_client_socket.h"
19
20 using base::TimeDelta;
21
22 namespace net {
23
24 SCTPSocketParams::SCTPSocketParams(const HostPortPair& host_port_pair,
25 RequestPriority priority,
26 const GURL& referrer,
27 bool disable_resolver_cache,
28 bool ignore_limits)
29 : destination_(host_port_pair), ignore_limits_(ignore_limits) {
30 Initialize(priority, referrer, disable_resolver_cache);
31 }
32
33 SCTPSocketParams::~SCTPSocketParams() {}
34
35 void SCTPSocketParams::Initialize(RequestPriority priority,
36 const GURL& referrer,
37 bool disable_resolver_cache) {
38 // The referrer is used by the DNS prefetch system to correlate resolutions
39 // with the page that triggered them. It doesn't impact the actual addresses
40 // that we resolve to.
41 destination_.set_referrer(referrer);
42 destination_.set_priority(priority);
43 if (disable_resolver_cache)
44 destination_.set_allow_cached_response(false);
45 }
46
47 // SCTPConnectJobs will time out after this many seconds. Note this is the
48 // total time, including both host resolution and SCTP connect() times.
49 //
50 // TODO(eroman): The use of this constant needs to be re-evaluated. The time
51 // needed for SCTPClientSocketXXX::Connect() can be arbitrarily long, since
52 // the address list may contain many alternatives, and most of those may
53 // timeout. Even worse, the per-connect timeout threshold varies greatly
54 // between systems (anywhere from 20 seconds to 190 seconds).
55 // See comment #12 at http://crbug.com/23364 for specifics.
56 static const int kSCTPConnectJobTimeoutInSeconds = 240; // 4 minutes.
57
58 SCTPConnectJob::SCTPConnectJob(
59 const std::string& group_name,
60 const scoped_refptr<SCTPSocketParams>& params,
61 base::TimeDelta timeout_duration,
62 ClientSocketFactory* client_socket_factory,
63 HostResolver* host_resolver,
64 Delegate* delegate,
65 NetLog* net_log)
66 : ConnectJob(group_name, timeout_duration, delegate,
67 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
68 params_(params),
69 client_socket_factory_(client_socket_factory),
70 ALLOW_THIS_IN_INITIALIZER_LIST(
71 callback_(this,
72 &SCTPConnectJob::OnIOComplete)),
73 resolver_(host_resolver) {}
74
75 SCTPConnectJob::~SCTPConnectJob() {
76 // We don't worry about cancelling the host resolution and SCTP connect, since
77 // ~SingleRequestHostResolver and ~ClientSocket will take care of it.
78 }
79
80 LoadState SCTPConnectJob::GetLoadState() const {
81 switch (next_state_) {
82 case STATE_RESOLVE_HOST:
83 case STATE_RESOLVE_HOST_COMPLETE:
84 return LOAD_STATE_RESOLVING_HOST;
85 case STATE_SCTP_CONNECT:
86 case STATE_SCTP_CONNECT_COMPLETE:
87 return LOAD_STATE_CONNECTING;
88 default:
89 NOTREACHED();
90 return LOAD_STATE_IDLE;
91 }
92 }
93
94 void SCTPConnectJob::OnIOComplete(int result) {
95 int rv = DoLoop(result);
96 if (rv != ERR_IO_PENDING)
97 NotifyDelegateOfCompletion(rv); // Deletes |this|
98 }
99
100 int SCTPConnectJob::DoLoop(int result) {
101 DCHECK_NE(next_state_, STATE_NONE);
102
103 int rv = result;
104 do {
105 State state = next_state_;
106 next_state_ = STATE_NONE;
107 switch (state) {
108 case STATE_RESOLVE_HOST:
109 DCHECK_EQ(OK, rv);
110 rv = DoResolveHost();
111 break;
112 case STATE_RESOLVE_HOST_COMPLETE:
113 rv = DoResolveHostComplete(rv);
114 break;
115 case STATE_SCTP_CONNECT:
116 DCHECK_EQ(OK, rv);
117 rv = DoSCTPConnect();
118 break;
119 case STATE_SCTP_CONNECT_COMPLETE:
120 rv = DoSCTPConnectComplete(rv);
121 break;
122 default:
123 NOTREACHED();
124 rv = ERR_FAILED;
125 break;
126 }
127 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
128
129 return rv;
130 }
131
132 int SCTPConnectJob::DoResolveHost() {
133 next_state_ = STATE_RESOLVE_HOST_COMPLETE;
134 return resolver_.Resolve(params_->destination(), &addresses_, &callback_,
135 net_log());
136 }
137
138 int SCTPConnectJob::DoResolveHostComplete(int result) {
139 if (result == OK)
140 next_state_ = STATE_SCTP_CONNECT;
141 return result;
142 }
143
144 int SCTPConnectJob::DoSCTPConnect() {
145 next_state_ = STATE_SCTP_CONNECT_COMPLETE;
146 set_socket(client_socket_factory_->CreateSCTPClientSocket(
147 addresses_, net_log().net_log(), net_log().source()));
148 connect_start_time_ = base::TimeTicks::Now();
149 return socket()->Connect(&callback_);
150 }
151
152 int SCTPConnectJob::DoSCTPConnectComplete(int result) {
153 if (result == OK) {
154 DCHECK(connect_start_time_ != base::TimeTicks());
155 DCHECK(start_time_ != base::TimeTicks());
156 base::TimeTicks now = base::TimeTicks::Now();
157 base::TimeDelta total_duration = now - start_time_;
158 UMA_HISTOGRAM_CUSTOM_TIMES(
159 "Net.DNS_Resolution_And_SCTP_Connection_Latency2",
160 total_duration,
161 base::TimeDelta::FromMilliseconds(1),
162 base::TimeDelta::FromMinutes(10),
163 100);
164
165 base::TimeDelta connect_duration = now - connect_start_time_;
166 UMA_HISTOGRAM_CUSTOM_TIMES("Net.SCTP_Connection_Latency",
167 connect_duration,
168 base::TimeDelta::FromMilliseconds(1),
169 base::TimeDelta::FromMinutes(10),
170 100);
171 } else {
172 // Delete the socket on error.
173 set_socket(NULL);
174 }
175
176 return result;
177 }
178
179 int SCTPConnectJob::ConnectInternal() {
180 next_state_ = STATE_RESOLVE_HOST;
181 start_time_ = base::TimeTicks::Now();
182 return DoLoop(OK);
183 }
184
185 ConnectJob* SCTPClientSocketPool::SCTPConnectJobFactory::NewConnectJob(
186 const std::string& group_name,
187 const PoolBase::Request& request,
188 ConnectJob::Delegate* delegate) const {
189 return new SCTPConnectJob(group_name, request.params(), ConnectionTimeout(),
190 client_socket_factory_, host_resolver_, delegate,
191 net_log_);
192 }
193
194 base::TimeDelta
195 SCTPClientSocketPool::SCTPConnectJobFactory::ConnectionTimeout() const {
196 return base::TimeDelta::FromSeconds(kSCTPConnectJobTimeoutInSeconds);
197 }
198
199 SCTPClientSocketPool::SCTPClientSocketPool(
200 int max_sockets,
201 int max_sockets_per_group,
202 ClientSocketPoolHistograms* histograms,
203 HostResolver* host_resolver,
204 ClientSocketFactory* client_socket_factory,
205 NetLog* net_log)
206 : base_(max_sockets, max_sockets_per_group, histograms,
207 base::TimeDelta::FromSeconds(
208 ClientSocketPool::unused_idle_socket_timeout()),
209 base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout),
210 new SCTPConnectJobFactory(client_socket_factory,
211 host_resolver, net_log)) {
212 base_.EnableConnectBackupJobs();
213 }
214
215 SCTPClientSocketPool::~SCTPClientSocketPool() {}
216
217 int SCTPClientSocketPool::RequestSocket(
218 const std::string& group_name,
219 const void* params,
220 RequestPriority priority,
221 ClientSocketHandle* handle,
222 CompletionCallback* callback,
223 const BoundNetLog& net_log) {
224 const scoped_refptr<SCTPSocketParams>* casted_params =
225 static_cast<const scoped_refptr<SCTPSocketParams>*>(params);
226
227 if (net_log.IsLoggingAllEvents()) {
228 // TODO(eroman): Split out the host and port parameters.
229 net_log.AddEvent(
230 NetLog::TYPE_SCTP_CLIENT_SOCKET_POOL_REQUESTED_SOCKET,
231 make_scoped_refptr(new NetLogStringParameter(
232 "host_and_port",
233 casted_params->get()->destination().host_port_pair().ToString())));
234 }
235
236 return base_.RequestSocket(group_name, *casted_params, priority, handle,
237 callback, net_log);
238 }
239
240 void SCTPClientSocketPool::RequestSockets(
241 const std::string& group_name,
242 const void* params,
243 int num_sockets,
244 const BoundNetLog& net_log) {
245 const scoped_refptr<SCTPSocketParams>* casted_params =
246 static_cast<const scoped_refptr<SCTPSocketParams>*>(params);
247
248 if (net_log.IsLoggingAllEvents()) {
249 // TODO(eroman): Split out the host and port parameters.
250 net_log.AddEvent(
251 NetLog::TYPE_SCTP_CLIENT_SOCKET_POOL_REQUESTED_SOCKETS,
252 make_scoped_refptr(new NetLogStringParameter(
253 "host_and_port",
254 casted_params->get()->destination().host_port_pair().ToString())));
255 }
256
257 base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
258 }
259
260 void SCTPClientSocketPool::CancelRequest(
261 const std::string& group_name,
262 ClientSocketHandle* handle) {
263 base_.CancelRequest(group_name, handle);
264 }
265
266 void SCTPClientSocketPool::ReleaseSocket(
267 const std::string& group_name,
268 ClientSocket* socket,
269 int id) {
270 base_.ReleaseSocket(group_name, socket, id);
271 }
272
273 void SCTPClientSocketPool::Flush() {
274 base_.Flush();
275 }
276
277 void SCTPClientSocketPool::CloseIdleSockets() {
278 base_.CloseIdleSockets();
279 }
280
281 int SCTPClientSocketPool::IdleSocketCount() const {
282 return base_.idle_socket_count();
283 }
284
285 int SCTPClientSocketPool::IdleSocketCountInGroup(
286 const std::string& group_name) const {
287 return base_.IdleSocketCountInGroup(group_name);
288 }
289
290 LoadState SCTPClientSocketPool::GetLoadState(
291 const std::string& group_name, const ClientSocketHandle* handle) const {
292 return base_.GetLoadState(group_name, handle);
293 }
294
295 DictionaryValue* SCTPClientSocketPool::GetInfoAsValue(
296 const std::string& name,
297 const std::string& type,
298 bool include_nested_pools) const {
299 return base_.GetInfoAsValue(name, type);
300 }
301
302 base::TimeDelta SCTPClientSocketPool::ConnectionTimeout() const {
303 return base_.ConnectionTimeout();
304 }
305
306 ClientSocketPoolHistograms* SCTPClientSocketPool::histograms() const {
307 return base_.histograms();
308 }
309
310 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698