| 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 bool ignore_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 ignore_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 bool ignore_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() && !ignore_limits) { |
| 290 request_net_log.AddEvent(NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS); | 293 request_net_log.AddEvent(NetLog::TYPE_SOCKET_POOL_STALLED_MAX_SOCKETS); |
| 291 // TODO(ricea): Use emplace_back when C++11 becomes allowed. | 294 // TODO(ricea): Use emplace_back when C++11 becomes allowed. |
| 292 StalledRequest request( | 295 StalledRequest request( |
| 293 casted_params, priority, handle, callback, request_net_log); | 296 casted_params, priority, handle, callback, request_net_log); |
| 294 stalled_request_queue_.push_back(request); | 297 stalled_request_queue_.push_back(request); |
| 295 StalledRequestQueue::iterator iterator = stalled_request_queue_.end(); | 298 StalledRequestQueue::iterator iterator = stalled_request_queue_.end(); |
| 296 --iterator; | 299 --iterator; |
| 297 DCHECK_EQ(handle, iterator->handle); | 300 DCHECK_EQ(handle, iterator->handle); |
| 298 // Because StalledRequestQueue is a std::list, its iterators are guaranteed | 301 // 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 | 302 // 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 | 303 // 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 | 304 // is safe to dereference an iterator in stalled_request_map_ to find the |
| 302 // corresponding list element. | 305 // corresponding list element. |
| 303 stalled_request_map_.insert( | 306 stalled_request_map_.insert( |
| 304 StalledRequestMap::value_type(handle, iterator)); | 307 StalledRequestMap::value_type(handle, iterator)); |
| 305 return ERR_IO_PENDING; | 308 return ERR_IO_PENDING; |
| 306 } | 309 } |
| 307 | 310 |
| 308 scoped_ptr<WebSocketTransportConnectJob> connect_job( | 311 scoped_ptr<WebSocketTransportConnectJob> connect_job( |
| 309 new WebSocketTransportConnectJob(group_name, | 312 new WebSocketTransportConnectJob( |
| 310 priority, | 313 group_name, priority, ignore_limits, casted_params, |
| 311 casted_params, | 314 ConnectionTimeout(), callback, client_socket_factory_, host_resolver_, |
| 312 ConnectionTimeout(), | 315 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 | 316 |
| 321 int rv = connect_job->Connect(); | 317 int rv = connect_job->Connect(); |
| 322 // Regardless of the outcome of |connect_job|, it will always be bound to | 318 // 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 | 319 // |handle|, since this pool uses early-binding. So the binding is logged |
| 324 // here, without waiting for the result. | 320 // here, without waiting for the result. |
| 325 request_net_log.AddEvent( | 321 request_net_log.AddEvent( |
| 326 NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB, | 322 NetLog::TYPE_SOCKET_POOL_BOUND_TO_CONNECT_JOB, |
| 327 connect_job->net_log().source().ToEventParametersCallback()); | 323 connect_job->net_log().source().ToEventParametersCallback()); |
| 328 if (rv == OK) { | 324 if (rv == OK) { |
| 329 HandOutSocket(connect_job->PassSocket(), | 325 HandOutSocket(connect_job->PassSocket(), |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 void WebSocketTransportClientSocketPool::ActivateStalledRequest() { | 578 void WebSocketTransportClientSocketPool::ActivateStalledRequest() { |
| 583 DCHECK(!stalled_request_queue_.empty()); | 579 DCHECK(!stalled_request_queue_.empty()); |
| 584 DCHECK(!ReachedMaxSocketsLimit()); | 580 DCHECK(!ReachedMaxSocketsLimit()); |
| 585 // Usually we will only be able to activate one stalled request at a time, | 581 // 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 | 582 // however if all the connects fail synchronously for some reason, we may be |
| 587 // able to clear the whole queue at once. | 583 // able to clear the whole queue at once. |
| 588 while (!stalled_request_queue_.empty() && !ReachedMaxSocketsLimit()) { | 584 while (!stalled_request_queue_.empty() && !ReachedMaxSocketsLimit()) { |
| 589 StalledRequest request(stalled_request_queue_.front()); | 585 StalledRequest request(stalled_request_queue_.front()); |
| 590 stalled_request_queue_.pop_front(); | 586 stalled_request_queue_.pop_front(); |
| 591 stalled_request_map_.erase(request.handle); | 587 stalled_request_map_.erase(request.handle); |
| 592 int rv = RequestSocket("ignored", | 588 int rv = |
| 593 &request.params, | 589 RequestSocket("ignored", &request.params, request.priority, |
| 594 request.priority, | 590 // stalled requests can't have |ignore_limits| set. |
| 595 request.handle, | 591 false, request.handle, request.callback, request.net_log); |
| 596 request.callback, | |
| 597 request.net_log); | |
| 598 // ActivateStalledRequest() never returns synchronously, so it is never | 592 // ActivateStalledRequest() never returns synchronously, so it is never |
| 599 // called re-entrantly. | 593 // called re-entrantly. |
| 600 if (rv != ERR_IO_PENDING) | 594 if (rv != ERR_IO_PENDING) |
| 601 InvokeUserCallbackLater(request.handle, request.callback, rv); | 595 InvokeUserCallbackLater(request.handle, request.callback, rv); |
| 602 } | 596 } |
| 603 } | 597 } |
| 604 | 598 |
| 605 bool WebSocketTransportClientSocketPool::DeleteStalledRequest( | 599 bool WebSocketTransportClientSocketPool::DeleteStalledRequest( |
| 606 ClientSocketHandle* handle) { | 600 ClientSocketHandle* handle) { |
| 607 StalledRequestMap::iterator it = stalled_request_map_.find(handle); | 601 StalledRequestMap::iterator it = stalled_request_map_.find(handle); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 634 const BoundNetLog& net_log) | 628 const BoundNetLog& net_log) |
| 635 : params(params), | 629 : params(params), |
| 636 priority(priority), | 630 priority(priority), |
| 637 handle(handle), | 631 handle(handle), |
| 638 callback(callback), | 632 callback(callback), |
| 639 net_log(net_log) {} | 633 net_log(net_log) {} |
| 640 | 634 |
| 641 WebSocketTransportClientSocketPool::StalledRequest::~StalledRequest() {} | 635 WebSocketTransportClientSocketPool::StalledRequest::~StalledRequest() {} |
| 642 | 636 |
| 643 } // namespace net | 637 } // namespace net |
| OLD | NEW |