Home | History | Annotate | Download | only in socket
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef NET_SOCKET_CLIENT_SOCKET_POOL_H_
      6 #define NET_SOCKET_CLIENT_SOCKET_POOL_H_
      7 
      8 #include <deque>
      9 #include <string>
     10 
     11 #include "base/basictypes.h"
     12 #include "base/memory/ref_counted.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/template_util.h"
     15 #include "base/time/time.h"
     16 #include "net/base/completion_callback.h"
     17 #include "net/base/load_states.h"
     18 #include "net/base/net_export.h"
     19 #include "net/base/request_priority.h"
     20 #include "net/dns/host_resolver.h"
     21 
     22 namespace base {
     23 class DictionaryValue;
     24 }
     25 
     26 namespace net {
     27 
     28 class ClientSocketHandle;
     29 class ClientSocketPoolHistograms;
     30 class StreamSocket;
     31 
     32 // ClientSocketPools are layered. This defines an interface for lower level
     33 // socket pools to communicate with higher layer pools.
     34 class NET_EXPORT HigherLayeredPool {
     35  public:
     36   virtual ~HigherLayeredPool() {}
     37 
     38   // Instructs the HigherLayeredPool to close an idle connection. Return true if
     39   // one was closed.  Closing an idle connection will call into the lower layer
     40   // pool it came from, so must be careful of re-entrancy when using this.
     41   virtual bool CloseOneIdleConnection() = 0;
     42 };
     43 
     44 // ClientSocketPools are layered. This defines an interface for higher level
     45 // socket pools to communicate with lower layer pools.
     46 class NET_EXPORT LowerLayeredPool {
     47  public:
     48   virtual ~LowerLayeredPool() {}
     49 
     50   // Returns true if a there is currently a request blocked on the per-pool
     51   // (not per-host) max socket limit, either in this pool, or one that it is
     52   // layered on top of.
     53   virtual bool IsStalled() const = 0;
     54 
     55   // Called to add or remove a higher layer pool on top of |this|.  A higher
     56   // layer pool may be added at most once to |this|, and must be removed prior
     57   // to destruction of |this|.
     58   virtual void AddHigherLayeredPool(HigherLayeredPool* higher_pool) = 0;
     59   virtual void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) = 0;
     60 };
     61 
     62 // A ClientSocketPool is used to restrict the number of sockets open at a time.
     63 // It also maintains a list of idle persistent sockets.
     64 //
     65 class NET_EXPORT ClientSocketPool : public LowerLayeredPool {
     66  public:
     67   // Subclasses must also have an inner class SocketParams which is
     68   // the type for the |params| argument in RequestSocket() and
     69   // RequestSockets() below.
     70 
     71   // Requests a connected socket for a group_name.
     72   //
     73   // There are five possible results from calling this function:
     74   // 1) RequestSocket returns OK and initializes |handle| with a reused socket.
     75   // 2) RequestSocket returns OK with a newly connected socket.
     76   // 3) RequestSocket returns ERR_IO_PENDING.  The handle will be added to a
     77   // wait list until a socket is available to reuse or a new socket finishes
     78   // connecting.  |priority| will determine the placement into the wait list.
     79   // 4) An error occurred early on, so RequestSocket returns an error code.
     80   // 5) A recoverable error occurred while setting up the socket.  An error
     81   // code is returned, but the |handle| is initialized with the new socket.
     82   // The caller must recover from the error before using the connection, or
     83   // Disconnect the socket before releasing or resetting the |handle|.
     84   // The current recoverable errors are: the errors accepted by
     85   // IsCertificateError(err) and PROXY_AUTH_REQUESTED, or
     86   // HTTPS_PROXY_TUNNEL_RESPONSE when reported by HttpProxyClientSocketPool.
     87   //
     88   // If this function returns OK, then |handle| is initialized upon return.
     89   // The |handle|'s is_initialized method will return true in this case.  If a
     90   // StreamSocket was reused, then ClientSocketPool will call
     91   // |handle|->set_reused(true).  In either case, the socket will have been
     92   // allocated and will be connected.  A client might want to know whether or
     93   // not the socket is reused in order to request a new socket if he encounters
     94   // an error with the reused socket.
     95   //
     96   // If ERR_IO_PENDING is returned, then the callback will be used to notify the
     97   // client of completion.
     98   //
     99   // Profiling information for the request is saved to |net_log| if non-NULL.
    100   virtual int RequestSocket(const std::string& group_name,
    101                             const void* params,
    102                             RequestPriority priority,
    103                             ClientSocketHandle* handle,
    104                             const CompletionCallback& callback,
    105                             const BoundNetLog& net_log) = 0;
    106 
    107   // RequestSockets is used to request that |num_sockets| be connected in the
    108   // connection group for |group_name|.  If the connection group already has
    109   // |num_sockets| idle sockets / active sockets / currently connecting sockets,
    110   // then this function doesn't do anything.  Otherwise, it will start up as
    111   // many connections as necessary to reach |num_sockets| total sockets for the
    112   // group.  It uses |params| to control how to connect the sockets.   The
    113   // ClientSocketPool will assign a priority to the new connections, if any.
    114   // This priority will probably be lower than all others, since this method
    115   // is intended to make sure ahead of time that |num_sockets| sockets are
    116   // available to talk to a host.
    117   virtual void RequestSockets(const std::string& group_name,
    118                               const void* params,
    119                               int num_sockets,
    120                               const BoundNetLog& net_log) = 0;
    121 
    122   // Called to cancel a RequestSocket call that returned ERR_IO_PENDING.  The
    123   // same handle parameter must be passed to this method as was passed to the
    124   // RequestSocket call being cancelled.  The associated CompletionCallback is
    125   // not run.  However, for performance, we will let one ConnectJob complete
    126   // and go idle.
    127   virtual void CancelRequest(const std::string& group_name,
    128                              ClientSocketHandle* handle) = 0;
    129 
    130   // Called to release a socket once the socket is no longer needed.  If the
    131   // socket still has an established connection, then it will be added to the
    132   // set of idle sockets to be used to satisfy future RequestSocket calls.
    133   // Otherwise, the StreamSocket is destroyed.  |id| is used to differentiate
    134   // between updated versions of the same pool instance.  The pool's id will
    135   // change when it flushes, so it can use this |id| to discard sockets with
    136   // mismatched ids.
    137   virtual void ReleaseSocket(const std::string& group_name,
    138                              scoped_ptr<StreamSocket> socket,
    139                              int id) = 0;
    140 
    141   // This flushes all state from the ClientSocketPool.  This means that all
    142   // idle and connecting sockets are discarded with the given |error|.
    143   // Active sockets being held by ClientSocketPool clients will be discarded
    144   // when released back to the pool.
    145   // Does not flush any pools wrapped by |this|.
    146   virtual void FlushWithError(int error) = 0;
    147 
    148   // Called to close any idle connections held by the connection manager.
    149   virtual void CloseIdleSockets() = 0;
    150 
    151   // The total number of idle sockets in the pool.
    152   virtual int IdleSocketCount() const = 0;
    153 
    154   // The total number of idle sockets in a connection group.
    155   virtual int IdleSocketCountInGroup(const std::string& group_name) const = 0;
    156 
    157   // Determine the LoadState of a connecting ClientSocketHandle.
    158   virtual LoadState GetLoadState(const std::string& group_name,
    159                                  const ClientSocketHandle* handle) const = 0;
    160 
    161   // Retrieves information on the current state of the pool as a
    162   // DictionaryValue.  Caller takes possession of the returned value.
    163   // If |include_nested_pools| is true, the states of any nested
    164   // ClientSocketPools will be included.
    165   virtual base::DictionaryValue* GetInfoAsValue(
    166       const std::string& name,
    167       const std::string& type,
    168       bool include_nested_pools) const = 0;
    169 
    170   // Returns the maximum amount of time to wait before retrying a connect.
    171   static const int kMaxConnectRetryIntervalMs = 250;
    172 
    173   // The set of histograms specific to this pool.  We can't use the standard
    174   // UMA_HISTOGRAM_* macros because they are callsite static.
    175   virtual ClientSocketPoolHistograms* histograms() const = 0;
    176 
    177   static base::TimeDelta unused_idle_socket_timeout();
    178   static void set_unused_idle_socket_timeout(base::TimeDelta timeout);
    179 
    180   static base::TimeDelta used_idle_socket_timeout();
    181   static void set_used_idle_socket_timeout(base::TimeDelta timeout);
    182 
    183  protected:
    184   ClientSocketPool();
    185   virtual ~ClientSocketPool();
    186 
    187   // Return the connection timeout for this pool.
    188   virtual base::TimeDelta ConnectionTimeout() const = 0;
    189 
    190  private:
    191   DISALLOW_COPY_AND_ASSIGN(ClientSocketPool);
    192 };
    193 
    194 template <typename PoolType>
    195 void RequestSocketsForPool(
    196     PoolType* pool,
    197     const std::string& group_name,
    198     const scoped_refptr<typename PoolType::SocketParams>& params,
    199     int num_sockets,
    200     const BoundNetLog& net_log) {
    201   pool->RequestSockets(group_name, &params, num_sockets, net_log);
    202 }
    203 
    204 }  // namespace net
    205 
    206 #endif  // NET_SOCKET_CLIENT_SOCKET_POOL_H_
    207