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