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