OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/websocket_transport_client_socket_pool.h" | 5 #include "net/socket/websocket_transport_client_socket_pool.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 // TODO(ricea): For now, we implement a global timeout for compatability with | 32 // TODO(ricea): For now, we implement a global timeout for compatability with |
33 // TransportConnectJob. Since WebSocketTransportConnectJob controls the address | 33 // TransportConnectJob. Since WebSocketTransportConnectJob controls the address |
34 // selection process more tightly, it could do something smarter here. | 34 // selection process more tightly, it could do something smarter here. |
35 const int kTransportConnectJobTimeoutInSeconds = 240; // 4 minutes. | 35 const int kTransportConnectJobTimeoutInSeconds = 240; // 4 minutes. |
36 | 36 |
37 } // namespace | 37 } // namespace |
38 | 38 |
39 WebSocketTransportConnectJob::WebSocketTransportConnectJob( | 39 WebSocketTransportConnectJob::WebSocketTransportConnectJob( |
40 const std::string& group_name, | 40 const std::string& group_name, |
41 RequestPriority priority, | 41 RequestPriority priority, |
| 42 ClientSocketPool::RespectLimits respect_limits, |
42 const scoped_refptr<TransportSocketParams>& params, | 43 const scoped_refptr<TransportSocketParams>& params, |
43 TimeDelta timeout_duration, | 44 TimeDelta timeout_duration, |
44 const CompletionCallback& callback, | 45 const CompletionCallback& callback, |
45 ClientSocketFactory* client_socket_factory, | 46 ClientSocketFactory* client_socket_factory, |
46 HostResolver* host_resolver, | 47 HostResolver* host_resolver, |
47 ClientSocketHandle* handle, | 48 ClientSocketHandle* handle, |
48 Delegate* delegate, | 49 Delegate* delegate, |
49 NetLog* pool_net_log, | 50 NetLog* pool_net_log, |
50 const BoundNetLog& request_net_log) | 51 const BoundNetLog& request_net_log) |
51 : ConnectJob(group_name, | 52 : ConnectJob(group_name, |
52 timeout_duration, | 53 timeout_duration, |
53 priority, | 54 priority, |
| 55 respect_limits, |
54 delegate, | 56 delegate, |
55 BoundNetLog::Make(pool_net_log, NetLog::SOURCE_CONNECT_JOB)), | 57 BoundNetLog::Make(pool_net_log, NetLog::SOURCE_CONNECT_JOB)), |
56 helper_(params, client_socket_factory, host_resolver, &connect_timing_), | 58 helper_(params, client_socket_factory, host_resolver, &connect_timing_), |
57 race_result_(TransportConnectJobHelper::CONNECTION_LATENCY_UNKNOWN), | 59 race_result_(TransportConnectJobHelper::CONNECTION_LATENCY_UNKNOWN), |
58 handle_(handle), | 60 handle_(handle), |
59 callback_(callback), | 61 callback_(callback), |
60 request_net_log_(request_net_log), | 62 request_net_log_(request_net_log), |
61 had_ipv4_(false), | 63 had_ipv4_(false), |
62 had_ipv6_(false) { | 64 had_ipv6_(false) { |
63 helper_.SetOnIOComplete(this); | 65 helper_.SetOnIOComplete(this); |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 DCHECK(handle->socket()); | 267 DCHECK(handle->socket()); |
266 IPEndPoint address; | 268 IPEndPoint address; |
267 if (handle->socket()->GetPeerAddress(&address) == OK) | 269 if (handle->socket()->GetPeerAddress(&address) == OK) |
268 WebSocketEndpointLockManager::GetInstance()->UnlockEndpoint(address); | 270 WebSocketEndpointLockManager::GetInstance()->UnlockEndpoint(address); |
269 } | 271 } |
270 | 272 |
271 int WebSocketTransportClientSocketPool::RequestSocket( | 273 int WebSocketTransportClientSocketPool::RequestSocket( |
272 const std::string& group_name, | 274 const std::string& group_name, |
273 const void* params, | 275 const void* params, |
274 RequestPriority priority, | 276 RequestPriority priority, |
| 277 RespectLimits respect_limits, |
275 ClientSocketHandle* handle, | 278 ClientSocketHandle* handle, |
276 const CompletionCallback& callback, | 279 const CompletionCallback& callback, |
277 const BoundNetLog& request_net_log) { | 280 const BoundNetLog& request_net_log) { |
278 DCHECK(params); | 281 DCHECK(params); |
279 const scoped_refptr<TransportSocketParams>& casted_params = | 282 const scoped_refptr<TransportSocketParams>& casted_params = |
280 *static_cast<const scoped_refptr<TransportSocketParams>*>(params); | 283 *static_cast<const scoped_refptr<TransportSocketParams>*>(params); |
281 | 284 |
282 NetLogTcpClientSocketPoolRequestedSocket(request_net_log, &casted_params); | 285 NetLogTcpClientSocketPoolRequestedSocket(request_net_log, &casted_params); |
283 | 286 |
284 CHECK(!callback.is_null()); | 287 CHECK(!callback.is_null()); |
285 CHECK(handle); | 288 CHECK(handle); |
286 | 289 |
287 request_net_log.BeginEvent(NetLog::TYPE_SOCKET_POOL); | 290 request_net_log.BeginEvent(NetLog::TYPE_SOCKET_POOL); |
288 | 291 |
289 if (ReachedMaxSocketsLimit() && !casted_params->ignore_limits()) { | 292 if (ReachedMaxSocketsLimit() && |
| 293 respect_limits == ClientSocketPool::RespectLimits::ENABLED) { |
290 request_net_log.AddEvent(NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS); | 294 request_net_log.AddEvent(NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS); |
291 // TODO(ricea): Use emplace_back when C++11 becomes allowed. | 295 // TODO(ricea): Use emplace_back when C++11 becomes allowed. |
292 StalledRequest request( | 296 StalledRequest request( |
293 casted_params, priority, handle, callback, request_net_log); | 297 casted_params, priority, handle, callback, request_net_log); |
294 stalled_request_queue_.push_back(request); | 298 stalled_request_queue_.push_back(request); |
295 StalledRequestQueue::iterator iterator = stalled_request_queue_.end(); | 299 StalledRequestQueue::iterator iterator = stalled_request_queue_.end(); |
296 --iterator; | 300 --iterator; |
297 DCHECK_EQ(handle, iterator->handle); | 301 DCHECK_EQ(handle, iterator->handle); |
298 // Because StalledRequestQueue is a std::list, its iterators are guaranteed | 302 // Because StalledRequestQueue is a std::list, its iterators are guaranteed |
299 // to remain valid as long as the elements are not removed. As long as | 303 // to remain valid as long as the elements are not removed. As long as |
300 // stalled_request_queue_ and stalled_request_map_ are updated in sync, it | 304 // stalled_request_queue_ and stalled_request_map_ are updated in sync, it |
301 // is safe to dereference an iterator in stalled_request_map_ to find the | 305 // is safe to dereference an iterator in stalled_request_map_ to find the |
302 // corresponding list element. | 306 // corresponding list element. |
303 stalled_request_map_.insert( | 307 stalled_request_map_.insert( |
304 StalledRequestMap::value_type(handle, iterator)); | 308 StalledRequestMap::value_type(handle, iterator)); |
305 return ERR_IO_PENDING; | 309 return ERR_IO_PENDING; |
306 } | 310 } |
307 | 311 |
308 scoped_ptr<WebSocketTransportConnectJob> connect_job( | 312 scoped_ptr<WebSocketTransportConnectJob> connect_job( |
309 new WebSocketTransportConnectJob(group_name, | 313 new WebSocketTransportConnectJob( |
310 priority, | 314 group_name, priority, respect_limits, casted_params, |
311 casted_params, | 315 ConnectionTimeout(), callback, client_socket_factory_, host_resolver_, |
312 ConnectionTimeout(), | 316 handle, &connect_job_delegate_, pool_net_log_, request_net_log)); |
313 callback, | |
314 client_socket_factory_, | |
315 host_resolver_, | |
316 handle, | |
317 &connect_job_delegate_, | |
318 pool_net_log_, | |
319 request_net_log)); | |
320 | 317 |
321 int rv = connect_job->Connect(); | 318 int rv = connect_job->Connect(); |
322 // Regardless of the outcome of |connect_job|, it will always be bound to | 319 // Regardless of the outcome of |connect_job|, it will always be bound to |
323 // |handle|, since this pool uses early-binding. So the binding is logged | 320 // |handle|, since this pool uses early-binding. So the binding is logged |
324 // here, without waiting for the result. | 321 // here, without waiting for the result. |
325 request_net_log.AddEvent( | 322 request_net_log.AddEvent( |
326 NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB, | 323 NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB, |
327 connect_job->net_log().source().ToEventParametersCallback()); | 324 connect_job->net_log().source().ToEventParametersCallback()); |
328 if (rv == OK) { | 325 if (rv == OK) { |
329 HandOutSocket(connect_job->PassSocket(), | 326 HandOutSocket(connect_job->PassSocket(), |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 void WebSocketTransportClientSocketPool::ActivateStalledRequest() { | 579 void WebSocketTransportClientSocketPool::ActivateStalledRequest() { |
583 DCHECK(!stalled_request_queue_.empty()); | 580 DCHECK(!stalled_request_queue_.empty()); |
584 DCHECK(!ReachedMaxSocketsLimit()); | 581 DCHECK(!ReachedMaxSocketsLimit()); |
585 // Usually we will only be able to activate one stalled request at a time, | 582 // Usually we will only be able to activate one stalled request at a time, |
586 // however if all the connects fail synchronously for some reason, we may be | 583 // however if all the connects fail synchronously for some reason, we may be |
587 // able to clear the whole queue at once. | 584 // able to clear the whole queue at once. |
588 while (!stalled_request_queue_.empty() && !ReachedMaxSocketsLimit()) { | 585 while (!stalled_request_queue_.empty() && !ReachedMaxSocketsLimit()) { |
589 StalledRequest request(stalled_request_queue_.front()); | 586 StalledRequest request(stalled_request_queue_.front()); |
590 stalled_request_queue_.pop_front(); | 587 stalled_request_queue_.pop_front(); |
591 stalled_request_map_.erase(request.handle); | 588 stalled_request_map_.erase(request.handle); |
592 int rv = RequestSocket("ignored", | 589 int rv = RequestSocket("ignored", &request.params, request.priority, |
593 &request.params, | 590 // Stalled requests can't have |respect_limits| |
594 request.priority, | 591 // DISABLED. |
595 request.handle, | 592 RespectLimits::ENABLED, request.handle, |
596 request.callback, | 593 request.callback, request.net_log); |
597 request.net_log); | |
598 // ActivateStalledRequest() never returns synchronously, so it is never | 594 // ActivateStalledRequest() never returns synchronously, so it is never |
599 // called re-entrantly. | 595 // called re-entrantly. |
600 if (rv != ERR_IO_PENDING) | 596 if (rv != ERR_IO_PENDING) |
601 InvokeUserCallbackLater(request.handle, request.callback, rv); | 597 InvokeUserCallbackLater(request.handle, request.callback, rv); |
602 } | 598 } |
603 } | 599 } |
604 | 600 |
605 bool WebSocketTransportClientSocketPool::DeleteStalledRequest( | 601 bool WebSocketTransportClientSocketPool::DeleteStalledRequest( |
606 ClientSocketHandle* handle) { | 602 ClientSocketHandle* handle) { |
607 StalledRequestMap::iterator it = stalled_request_map_.find(handle); | 603 StalledRequestMap::iterator it = stalled_request_map_.find(handle); |
(...skipping 26 matching lines...) Expand all Loading... |
634 const BoundNetLog& net_log) | 630 const BoundNetLog& net_log) |
635 : params(params), | 631 : params(params), |
636 priority(priority), | 632 priority(priority), |
637 handle(handle), | 633 handle(handle), |
638 callback(callback), | 634 callback(callback), |
639 net_log(net_log) {} | 635 net_log(net_log) {} |
640 | 636 |
641 WebSocketTransportClientSocketPool::StalledRequest::~StalledRequest() {} | 637 WebSocketTransportClientSocketPool::StalledRequest::~StalledRequest() {} |
642 | 638 |
643 } // namespace net | 639 } // namespace net |
OLD | NEW |