15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A ClientSocketPoolBase is used to restrict the number of sockets open at 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a time. It also maintains a list of idle persistent sockets for reuse. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Subclasses of ClientSocketPool should compose ClientSocketPoolBase to handle 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the core logic of (1) restricting the number of active (connected or 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connecting) sockets per "group" (generally speaking, the hostname), (2) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// maintaining a per-group list of idle, persistent sockets for reuse, and (3) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// limiting the total number of active sockets in the system. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ClientSocketPoolBase abstracts socket connection details behind ConnectJob, 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ConnectJobFactory, and SocketParams. When a socket "slot" becomes available, 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the ClientSocketPoolBase will ask the ConnectJobFactory to create a 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ConnectJob with a SocketParams. Subclasses of ClientSocketPool should 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implement their socket specific connection by subclassing ConnectJob and 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implementing ConnectJob::ConnectInternal(). They can control the parameters 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// passed to each new ConnectJob instance via their ConnectJobFactory subclass 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and templated SocketParams parameter. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include <cstddef> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/address_list.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_states.h" 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_timing_info.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/network_change_notifier.h" 471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/base/priority_queue.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/request_priority.h" 4923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "net/socket/client_socket_handle.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_pool.h" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/stream_socket.h" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClientSocketHandle; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ConnectJob provides an abstract interface for "connecting" a socket. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The connection may involve host resolution, tcp connection, ssl connection, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// etc. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE ConnectJob { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class NET_EXPORT_PRIVATE Delegate { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate() {} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Delegate() {} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Alerts the delegate that the connection completed. |job| must 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // be destroyed by the delegate. A scoped_ptr<> isn't used because 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the caller of this function doesn't own |job|. 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual void OnConnectJobComplete(int result, 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ConnectJob* job) = 0; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Delegate); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A |timeout_duration| of 0 corresponds to no timeout. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConnectJob(const std::string& group_name, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta timeout_duration, 803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RequestPriority priority, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate, 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ConnectJob(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Accessors 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& group_name() const { return group_name_; } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log() { return net_log_; } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Releases ownership of the underlying socket to the caller. 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Returns the released socket, or NULL if there was a connection 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // error. 923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<StreamSocket> PassSocket(); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Begins connecting the socket. Returns OK on success, ERR_IO_PENDING if it 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cannot complete synchronously without blocking, or another net error code 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on error. In asynchronous completion, the ConnectJob will notify 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |delegate_| via OnConnectJobComplete. In both asynchronous and synchronous 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // completion, ReleaseSocket() can be called to acquire the connected socket 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if it succeeded. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int Connect(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual LoadState GetLoadState() const = 0; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If Connect returns an error (or OnConnectJobComplete reports an error 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // result) this method will be called, allowing the pool to add 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // additional error state to the ClientSocketHandle (post late-binding). 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void GetAdditionalErrorState(ClientSocketHandle* handle) {} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LoadTimingInfo::ConnectTiming& connect_timing() const { 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return connect_timing_; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log() const { return net_log_; } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RequestPriority priority() const { return priority_; } 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void SetSocket(scoped_ptr<StreamSocket> socket); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StreamSocket* socket() { return socket_.get(); } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void NotifyDelegateOfCompletion(int rv); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResetTimer(base::TimeDelta remainingTime); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Connection establishment timing information. 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LoadTimingInfo::ConnectTiming connect_timing_; 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int ConnectInternal() = 0; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void LogConnectStart(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void LogConnectCompletion(int net_error); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Alerts the delegate that the ConnectJob has timed out. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnTimeout(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string group_name_; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta timeout_duration_; 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(akalin): Support reprioritization. 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const RequestPriority priority_; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Timer to abort jobs that take too long. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::OneShotTimer<ConnectJob> timer_; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate_; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<StreamSocket> socket_; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog net_log_; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A ConnectJob is idle until Connect() has been called. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool idle_; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ConnectJob); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ClientSocketPoolBaseHelper is an internal class that implements almost all 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the functionality from ClientSocketPoolBase without using templates. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ClientSocketPoolBase adds templated definitions built on top of 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ClientSocketPoolBaseHelper. This class is not for external use, please use 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ClientSocketPoolBase instead. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE ClientSocketPoolBaseHelper 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public ConnectJob::Delegate, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public NetworkChangeNotifier::IPAddressObserver { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef uint32 Flags; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used to specify specific behavior for the ClientSocketPool. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum Flag { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NORMAL = 0, // Normal behavior. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NO_IDLE_SOCKETS = 0x1, // Do not return an idle socket. Create a new one. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class NET_EXPORT_PRIVATE Request { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Request(ClientSocketHandle* handle, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback, 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestPriority priority, 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ignore_limits, 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Flags flags, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Request(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketHandle* handle() const { return handle_; } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback() const { return callback_; } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestPriority priority() const { return priority_; } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ignore_limits() const { return ignore_limits_; } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Flags flags() const { return flags_; } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log() const { return net_log_; } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketHandle* const handle_; 1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const CompletionCallback callback_; 1893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(akalin): Support reprioritization. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RequestPriority priority_; 1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const bool ignore_limits_; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Flags flags_; 1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const BoundNetLog net_log_; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Request); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class ConnectJobFactory { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConnectJobFactory() {} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ConnectJobFactory() {} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual scoped_ptr<ConnectJob> NewConnectJob( 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& group_name, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Request& request, 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConnectJob::Delegate* delegate) const = 0; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual base::TimeDelta ConnectionTimeout() const = 0; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ConnectJobFactory); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketPoolBaseHelper( 2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) HigherLayeredPool* pool, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_sockets, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_sockets_per_group, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta unused_idle_socket_timeout, 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta used_idle_socket_timeout, 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConnectJobFactory* connect_job_factory); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ClientSocketPoolBaseHelper(); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Adds a lower layered pool to |this|, and adds |this| as a higher layered 2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // pool on top of |lower_pool|. 2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void AddLowerLayeredPool(LowerLayeredPool* lower_pool); 2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // See LowerLayeredPool::IsStalled for documentation on this function. 2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool IsStalled() const; 2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // See LowerLayeredPool for documentation on these functions. It is expected 2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // in the destructor that no higher layer pools remain. 2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void AddHigherLayeredPool(HigherLayeredPool* higher_pool); 2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See ClientSocketPool::RequestSocket for documentation on this function. 2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int RequestSocket(const std::string& group_name, 2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<const Request> request); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See ClientSocketPool::RequestSocket for documentation on this function. 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RequestSockets(const std::string& group_name, 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Request& request, 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_sockets); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See ClientSocketPool::CancelRequest for documentation on this function. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CancelRequest(const std::string& group_name, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketHandle* handle); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See ClientSocketPool::ReleaseSocket for documentation on this function. 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReleaseSocket(const std::string& group_name, 2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<StreamSocket> socket, 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int id); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // See ClientSocketPool::FlushWithError for documentation on this function. 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void FlushWithError(int error); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See ClientSocketPool::CloseIdleSockets for documentation on this function. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CloseIdleSockets(); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See ClientSocketPool::IdleSocketCount() for documentation on this function. 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idle_socket_count() const { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return idle_socket_count_; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See ClientSocketPool::IdleSocketCountInGroup() for documentation on this 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // function. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int IdleSocketCountInGroup(const std::string& group_name) const; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See ClientSocketPool::GetLoadState() for documentation on this function. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadState GetLoadState(const std::string& group_name, 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClientSocketHandle* handle) const; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta ConnectRetryInterval() const { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mbelshe): Make this tuned dynamically based on measured RTT. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For now, just use the max retry interval. 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::TimeDelta::FromMilliseconds( 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketPool::kMaxConnectRetryIntervalMs); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int NumUnassignedConnectJobsInGroup(const std::string& group_name) const { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return group_map_.find(group_name)->second->unassigned_job_count(); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int NumConnectJobsInGroup(const std::string& group_name) const { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return group_map_.find(group_name)->second->jobs().size(); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int NumActiveSocketsInGroup(const std::string& group_name) const { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return group_map_.find(group_name)->second->active_socket_count(); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasGroup(const std::string& group_name) const; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called to enable/disable cleaning up idle sockets. When enabled, 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // idle sockets that have been around for longer than a period defined 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by kCleanupInterval are cleaned up using a timer. Otherwise they are 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // closed next time client makes a request. This may reduce network 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // activity and power consumption. 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool cleanup_timer_enabled(); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool set_cleanup_timer_enabled(bool enabled); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Closes all idle sockets if |force| is true. Else, only closes idle 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sockets that timed out or can't be reused. Made public for testing. 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CleanupIdleSockets(bool force); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Closes one idle socket. Picks the first one encountered. 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(willchan): Consider a better algorithm for doing this. Perhaps we 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should keep an ordered list of idle sockets, and close them in order. 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Requires maintaining more state. It's not clear if it's worth it since 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // I'm not sure if we hit this situation often. 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CloseOneIdleSocket(); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Checks higher layered pools to see if they can close an idle connection. 3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool CloseOneIdleConnectionInHigherLayeredPool(); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See ClientSocketPool::GetInfoAsValue for documentation on this function. 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::DictionaryValue* GetInfoAsValue(const std::string& name, 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& type) const; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta ConnectionTimeout() const { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return connect_job_factory_->ConnectionTimeout(); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool connect_backup_jobs_enabled(); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool set_connect_backup_jobs_enabled(bool enabled); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EnableConnectBackupJobs(); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ConnectJob::Delegate methods: 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnConnectJobComplete(int result, ConnectJob* job) OVERRIDE; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NetworkChangeNotifier::IPAddressObserver methods: 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnIPAddressChanged() OVERRIDE; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCounted<ClientSocketPoolBaseHelper>; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Entry for a persistent socket which became idle at time |start_time|. 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct IdleSocket { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IdleSocket() : socket(NULL) {} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 342effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // An idle socket can't be used if it is disconnected or has been used 343effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // before and has received data unexpectedly (hence no longer idle). The 344effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // unread data would be mistaken for the beginning of the next response if 345effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // we were to use the socket for a new request. 346effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // 347effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Note that a socket that has never been used before (like a preconnected 348effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // socket) may be used even with unread data. This may be, e.g., a SPDY 349effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // SETTINGS frame. 350effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool IsUsable() const; 351effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An idle socket should be removed if it can't be reused, or has been idle 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for too long. |now| is the current time value (TimeTicks::Now()). 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |timeout| is the length of time to wait before timing out an idle socket. 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ShouldCleanup(base::TimeTicks now, base::TimeDelta timeout) const; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StreamSocket* socket; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks start_time; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) typedef PriorityQueue<const Request*> RequestQueue; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<const ClientSocketHandle*, const Request*> RequestMap; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A Group is allocated per group_name when there are idle sockets or pending 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // requests. Otherwise, the Group object is removed from the map. 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |active_socket_count| tracks the number of sockets held by clients. 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Group { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Group(); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Group(); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsEmpty() const { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return active_socket_count_ == 0 && idle_sockets_.empty() && 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jobs_.empty() && pending_requests_.empty(); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasAvailableSocketSlot(int max_sockets_per_group) const { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NumActiveSocketSlots() < max_sockets_per_group; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int NumActiveSocketSlots() const { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return active_socket_count_ + static_cast<int>(jobs_.size()) + 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(idle_sockets_.size()); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsStalledOnPoolMaxSockets(int max_sockets_per_group) const { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HasAvailableSocketSlot(max_sockets_per_group) && 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_requests_.size() > jobs_.size(); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Returns the priority of the top of the pending request queue 3921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // (which may be less than the maximum priority over the entire 3931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // queue, due to how we prioritize requests with |ignore_limits| 3941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // set over others). 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestPriority TopPendingPriority() const { 3961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // NOTE: FirstMax().value()->priority() is not the same as 3971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // FirstMax().priority()! 3981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return pending_requests_.FirstMax().value()->priority(); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Set a timer to create a backup job if it takes too long to 4021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // create one and if a timer isn't already running. 4031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void StartBackupJobTimer(const std::string& group_name, 4041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ClientSocketPoolBaseHelper* pool); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool BackupJobTimerIsRunning() const; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there's a ConnectJob that's never been assigned to Request, 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // decrements |unassigned_job_count_| and returns true. 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, returns false. 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool TryToUseUnassignedConnectJob(); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void AddJob(scoped_ptr<ConnectJob> job, bool is_preconnect); 4143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Remove |job| from this group, which must already own |job|. 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RemoveJob(ConnectJob* job); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RemoveAllJobs(); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool has_pending_requests() const { 4193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return !pending_requests_.empty(); 4203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) size_t pending_request_count() const { 4233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return pending_requests_.size(); 4243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Gets (but does not remove) the next pending request. Returns 4273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // NULL if there are no pending requests. 4283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Request* GetNextPendingRequest() const; 4293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Returns true if there is a connect job for |handle|. 4313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool HasConnectJobForHandle(const ClientSocketHandle* handle) const; 4323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Inserts the request into the queue based on priority 4343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // order. Older requests are prioritized over requests of equal 4353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // priority. 4361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void InsertPendingRequest(scoped_ptr<const Request> request); 4373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Gets and removes the next pending request. Returns NULL if 4393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // there are no pending requests. 4403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<const Request> PopNextPendingRequest(); 4413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Finds the pending request for |handle| and removes it. Returns 4433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the removed pending request, or NULL if there was none. 4443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<const Request> FindAndRemovePendingRequest( 4453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ClientSocketHandle* handle); 4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void IncrementActiveSocketCount() { active_socket_count_++; } 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DecrementActiveSocketCount() { active_socket_count_--; } 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int unassigned_job_count() const { return unassigned_job_count_; } 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::set<ConnectJob*>& jobs() const { return jobs_; } 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::list<IdleSocket>& idle_sockets() const { return idle_sockets_; } 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int active_socket_count() const { return active_socket_count_; } 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<IdleSocket>* mutable_idle_sockets() { return &idle_sockets_; } 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 4573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Returns the iterator's pending request after removing it from 4583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the queue. 4593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<const Request> RemovePendingRequest( 4601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const RequestQueue::Pointer& pointer); 4613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when the backup socket timer fires. 4631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) void OnBackupJobTimerFired( 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string group_name, 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketPoolBaseHelper* pool); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checks that |unassigned_job_count_| does not execeed the number of 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ConnectJobs. 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SanityCheck(); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Total number of ConnectJobs that have never been assigned to a Request. 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since jobs use late binding to requests, which ConnectJobs have or have 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not been assigned to a request are not tracked. This is incremented on 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // preconnect and decremented when a preconnect is assigned, or when there 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are fewer than |unassigned_job_count_| ConnectJobs. Not incremented 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when a request is cancelled. 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t unassigned_job_count_; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<IdleSocket> idle_sockets_; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<ConnectJob*> jobs_; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestQueue pending_requests_; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int active_socket_count_; // number of active sockets used by clients 4831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // A timer for when to start the backup job. 4841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::OneShotTimer<Group> backup_job_timer_; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<std::string, Group*> GroupMap; 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::set<ConnectJob*> ConnectJobSet; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct CallbackResultPair { 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallbackResultPair(); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallbackResultPair(const CompletionCallback& callback_in, int result_in); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~CallbackResultPair(); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback callback; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<const ClientSocketHandle*, CallbackResultPair> 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingCallbackMap; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Group* GetOrCreateGroup(const std::string& group_name); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RemoveGroup(const std::string& group_name); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RemoveGroup(GroupMap::iterator it); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when the number of idle sockets changes. 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void IncrementIdleCount(); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DecrementIdleCount(); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start cleanup timer for idle sockets. 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartIdleSocketTimer(); 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Scans the group map for groups which have an available socket slot and 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // at least one pending request. Returns true if any groups are stalled, and 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if so (and if both |group| and |group_name| are not NULL), fills |group| 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and |group_name| with data of the stalled group having highest priority. 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool FindTopStalledGroup(Group** group, std::string* group_name) const; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when timer_ fires. This method scans the idle sockets removing 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sockets that timed out or can't be reused. 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnCleanupTimerFired() { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CleanupIdleSockets(false); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Removes |job| from |group|, which must already own |job|. 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RemoveConnectJob(ConnectJob* job, Group* group); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tries to see if we can handle any more requests for |group|. 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnAvailableSocketSlot(const std::string& group_name, Group* group); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Process a pending socket request for a group. 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ProcessPendingRequest(const std::string& group_name, Group* group); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assigns |socket| to |handle| and updates |group|'s counters appropriately. 5363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void HandOutSocket(scoped_ptr<StreamSocket> socket, 53723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ClientSocketHandle::SocketReuseType reuse_type, 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LoadTimingInfo::ConnectTiming& connect_timing, 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketHandle* handle, 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta time_idle, 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Group* group, 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds |socket| to the list of idle sockets for |group|. 5453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void AddIdleSocket(scoped_ptr<StreamSocket> socket, Group* group); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Iterates through |group_map_|, canceling all ConnectJobs and deleting 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // groups if they are no longer needed. 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CancelAllConnectJobs(); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Iterates through |group_map_|, posting |error| callbacks for all 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // requests, and then deleting groups if they are no longer needed. 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void CancelAllRequestsWithError(int error); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if we can't create any more sockets due to the total limit. 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ReachedMaxSocketsLimit() const; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is the internal implementation of RequestSocket(). It differs in that 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it does not handle logging into NetLog of the queueing status of 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |request|. 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int RequestSocketInternal(const std::string& group_name, 5623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Request& request); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Assigns an idle socket for the group to the request. 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns |true| if an idle socket is available, false otherwise. 5663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool AssignIdleSocketToRequest(const Request& request, Group* group); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void LogBoundConnectJobToRequest( 5693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const NetLog::Source& connect_job_source, const Request& request); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Same as CloseOneIdleSocket() except it won't close an idle socket in 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |group|. If |group| is NULL, it is ignored. Returns true if it closed a 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // socket. 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CloseOneIdleSocketExceptInGroup(const Group* group); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checks if there are stalled socket groups that should be notified 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for possible wakeup. 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CheckForStalledSocketGroups(); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Posts a task to call InvokeUserCallback() on the next iteration through the 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // current message loop. Inserts |callback| into |pending_callback_map_|, 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // keyed by |handle|. 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InvokeUserCallbackLater( 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketHandle* handle, const CompletionCallback& callback, int rv); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invokes the user callback for |handle|. By the time this task has run, 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it's possible that the request has been cancelled, so |handle| may not 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // exist in |pending_callback_map_|. We look up the callback and result code 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in |pending_callback_map_|. 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InvokeUserCallback(ClientSocketHandle* handle); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Tries to close idle sockets in a higher level socket pool as long as this 593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // this pool is stalled. 594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void TryToCloseSocketsInLayeredPools(); 595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GroupMap group_map_; 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Map of the ClientSocketHandles for which we have a pending Task to invoke a 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callback. This is necessary since, before we invoke said callback, it's 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // possible that the request is cancelled. 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingCallbackMap pending_callback_map_; 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Timer used to periodically prune idle sockets that timed out or can't be 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reused. 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::RepeatingTimer<ClientSocketPoolBaseHelper> timer_; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The total number of idle sockets in the system. 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idle_socket_count_; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Number of connecting sockets across all groups. 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int connecting_socket_count_; 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Number of connected sockets we handed out across all groups. 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int handed_out_socket_count_; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The maximum total number of sockets. See ReachedMaxSocketsLimit. 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int max_sockets_; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The maximum number of sockets kept per group. 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int max_sockets_per_group_; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether to use timer to cleanup idle sockets. 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool use_cleanup_timer_; 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The time to wait until closing idle sockets. 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta unused_idle_socket_timeout_; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta used_idle_socket_timeout_; 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_ptr<ConnectJobFactory> connect_job_factory_; 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(vandebo) Remove when backup jobs move to TransportClientSocketPool 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool connect_backup_jobs_enabled_; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A unique id for the pool. It gets incremented every time we 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // FlushWithError() the pool. This is so that when sockets get released back 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to the pool, we can make sure that they are discarded rather than reused. 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pool_generation_number_; 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Used to add |this| as a higher layer pool on top of lower layer pools. May 6403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // be NULL if no lower layer pools will be added. 6413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) HigherLayeredPool* pool_; 6423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 6433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Pools that create connections through |this|. |this| will try to close 6443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // their idle sockets when it stalls. Must be empty on destruction. 6453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::set<HigherLayeredPool*> higher_pools_; 6463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 6473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Pools that this goes through. Typically there's only one, but not always. 6483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // |this| will check if they're stalled when it has a new idle socket. |this| 6493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // will remove itself from all lower layered pools on destruction. 6503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::set<LowerLayeredPool*> lower_pools_; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<ClientSocketPoolBaseHelper> weak_factory_; 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBaseHelper); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internal 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename SocketParams> 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClientSocketPoolBase { 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Request : public internal::ClientSocketPoolBaseHelper::Request { 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Request(ClientSocketHandle* handle, 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback, 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestPriority priority, 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ClientSocketPoolBaseHelper::Flags flags, 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ignore_limits, 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<SocketParams>& params, 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : internal::ClientSocketPoolBaseHelper::Request( 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle, callback, priority, ignore_limits, flags, net_log), 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_(params) {} 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<SocketParams>& params() const { return params_; } 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<SocketParams> params_; 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class ConnectJobFactory { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConnectJobFactory() {} 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ConnectJobFactory() {} 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual scoped_ptr<ConnectJob> NewConnectJob( 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& group_name, 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Request& request, 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConnectJob::Delegate* delegate) const = 0; 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual base::TimeDelta ConnectionTimeout() const = 0; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ConnectJobFactory); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |max_sockets| is the maximum number of sockets to be maintained by this 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ClientSocketPool. |max_sockets_per_group| specifies the maximum number of 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sockets a "group" can have. |unused_idle_socket_timeout| specifies how 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // long to leave an unused idle socket open before closing it. 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |used_idle_socket_timeout| specifies how long to leave a previously used 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // idle socket open before closing it. 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketPoolBase( 7043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) HigherLayeredPool* self, 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_sockets, 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_sockets_per_group, 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketPoolHistograms* histograms, 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta unused_idle_socket_timeout, 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta used_idle_socket_timeout, 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConnectJobFactory* connect_job_factory) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : histograms_(histograms), 7123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) helper_(self, max_sockets, max_sockets_per_group, 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unused_idle_socket_timeout, used_idle_socket_timeout, 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ConnectJobFactoryAdaptor(connect_job_factory)) {} 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ClientSocketPoolBase() {} 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These member functions simply forward to ClientSocketPoolBaseHelper. 7193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void AddLowerLayeredPool(LowerLayeredPool* lower_pool) { 7203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) helper_.AddLowerLayeredPool(lower_pool); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void AddHigherLayeredPool(HigherLayeredPool* higher_pool) { 7243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) helper_.AddHigherLayeredPool(higher_pool); 7253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 7263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) { 7283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) helper_.RemoveHigherLayeredPool(higher_pool); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RequestSocket bundles up the parameters into a Request and then forwards to 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ClientSocketPoolBaseHelper::RequestSocket(). 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int RequestSocket(const std::string& group_name, 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<SocketParams>& params, 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestPriority priority, 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketHandle* handle, 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback, 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) { 7393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<const Request> request( 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new Request(handle, callback, priority, 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ClientSocketPoolBaseHelper::NORMAL, 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->ignore_limits(), 7433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params, net_log)); 7443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return helper_.RequestSocket( 7453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) group_name, 7463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request.template PassAs< 7473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const internal::ClientSocketPoolBaseHelper::Request>()); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RequestSockets bundles up the parameters into a Request and then forwards 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to ClientSocketPoolBaseHelper::RequestSockets(). Note that it assigns the 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // priority to DEFAULT_PRIORITY and specifies the NO_IDLE_SOCKETS flag. 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RequestSockets(const std::string& group_name, 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<SocketParams>& params, 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_sockets, 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) { 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Request request(NULL /* no handle */, 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompletionCallback(), 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DEFAULT_PRIORITY, 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ClientSocketPoolBaseHelper::NO_IDLE_SOCKETS, 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params->ignore_limits(), 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params, 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper_.RequestSockets(group_name, request, num_sockets); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CancelRequest(const std::string& group_name, 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketHandle* handle) { 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helper_.CancelRequest(group_name, handle); 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) void ReleaseSocket(const std::string& group_name, 7733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<StreamSocket> socket, 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int id) { 7753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return helper_.ReleaseSocket(group_name, socket.Pass(), id); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void FlushWithError(int error) { helper_.FlushWithError(error); } 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsStalled() const { return helper_.IsStalled(); } 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CloseIdleSockets() { return helper_.CloseIdleSockets(); } 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idle_socket_count() const { return helper_.idle_socket_count(); } 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int IdleSocketCountInGroup(const std::string& group_name) const { 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helper_.IdleSocketCountInGroup(group_name); 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadState GetLoadState(const std::string& group_name, 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ClientSocketHandle* handle) const { 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helper_.GetLoadState(group_name, handle); 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnConnectJobComplete(int result, ConnectJob* job) { 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helper_.OnConnectJobComplete(result, job); 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int NumUnassignedConnectJobsInGroup(const std::string& group_name) const { 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helper_.NumUnassignedConnectJobsInGroup(group_name); 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int NumConnectJobsInGroup(const std::string& group_name) const { 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helper_.NumConnectJobsInGroup(group_name); 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int NumActiveSocketsInGroup(const std::string& group_name) const { 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helper_.NumActiveSocketsInGroup(group_name); 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasGroup(const std::string& group_name) const { 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helper_.HasGroup(group_name); 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CleanupIdleSockets(bool force) { 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helper_.CleanupIdleSockets(force); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::DictionaryValue* GetInfoAsValue(const std::string& name, 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& type) const { 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helper_.GetInfoAsValue(name, type); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta ConnectionTimeout() const { 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return helper_.ConnectionTimeout(); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketPoolHistograms* histograms() const { 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return histograms_; 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void EnableConnectBackupJobs() { helper_.EnableConnectBackupJobs(); } 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CloseOneIdleSocket() { return helper_.CloseOneIdleSocket(); } 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool CloseOneIdleConnectionInHigherLayeredPool() { 8373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return helper_.CloseOneIdleConnectionInHigherLayeredPool(); 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This adaptor class exists to bridge the 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // internal::ClientSocketPoolBaseHelper::ConnectJobFactory and 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ClientSocketPoolBase::ConnectJobFactory types, allowing clients to use the 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // typesafe ClientSocketPoolBase::ConnectJobFactory, rather than having to 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // static_cast themselves. 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class ConnectJobFactoryAdaptor 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public internal::ClientSocketPoolBaseHelper::ConnectJobFactory { 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef typename ClientSocketPoolBase<SocketParams>::ConnectJobFactory 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConnectJobFactory; 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit ConnectJobFactoryAdaptor(ConnectJobFactory* connect_job_factory) 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : connect_job_factory_(connect_job_factory) {} 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~ConnectJobFactoryAdaptor() {} 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) virtual scoped_ptr<ConnectJob> NewConnectJob( 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& group_name, 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const internal::ClientSocketPoolBaseHelper::Request& request, 8593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ConnectJob::Delegate* delegate) const OVERRIDE { 8603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Request& casted_request = static_cast<const Request&>(request); 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return connect_job_factory_->NewConnectJob( 8623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) group_name, casted_request, delegate); 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual base::TimeDelta ConnectionTimeout() const { 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return connect_job_factory_->ConnectionTimeout(); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_ptr<ConnectJobFactory> connect_job_factory_; 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Histograms for the pool 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketPoolHistograms* const histograms_; 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::ClientSocketPoolBaseHelper helper_; 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ 882