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