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.
5 #ifndef NET_SOCKET_CLIENT_SOCKET_POOL_H_
6 #define NET_SOCKET_CLIENT_SOCKET_POOL_H_
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"
23 class DictionaryValue
;
28 class ClientSocketHandle
;
29 class ClientSocketPoolHistograms
;
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
{
36 virtual ~HigherLayeredPool() {}
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;
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
{
48 virtual ~LowerLayeredPool() {}
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
53 virtual bool IsStalled() const = 0;
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;
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.
65 class NET_EXPORT ClientSocketPool
: public LowerLayeredPool
{
67 // Subclasses must also have an inner class SocketParams which is
68 // the type for the |params| argument in RequestSocket() and
69 // RequestSockets() below.
71 // Requests a connected socket for a group_name.
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.
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.
96 // If ERR_IO_PENDING is returned, then the callback will be used to notify the
97 // client of completion.
99 // Profiling information for the request is saved to |net_log| if non-NULL.
100 virtual int RequestSocket(const std::string
& group_name
,
102 RequestPriority priority
,
103 ClientSocketHandle
* handle
,
104 const CompletionCallback
& callback
,
105 const BoundNetLog
& net_log
) = 0;
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
,
120 const BoundNetLog
& net_log
) = 0;
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
127 virtual void CancelRequest(const std::string
& group_name
,
128 ClientSocketHandle
* handle
) = 0;
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
137 virtual void ReleaseSocket(const std::string
& group_name
,
138 scoped_ptr
<StreamSocket
> socket
,
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;
148 // Called to close any idle connections held by the connection manager.
149 virtual void CloseIdleSockets() = 0;
151 // The total number of idle sockets in the pool.
152 virtual int IdleSocketCount() const = 0;
154 // The total number of idle sockets in a connection group.
155 virtual int IdleSocketCountInGroup(const std::string
& group_name
) const = 0;
157 // Determine the LoadState of a connecting ClientSocketHandle.
158 virtual LoadState
GetLoadState(const std::string
& group_name
,
159 const ClientSocketHandle
* handle
) const = 0;
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;
170 // Returns the maximum amount of time to wait before retrying a connect.
171 static const int kMaxConnectRetryIntervalMs
= 250;
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;
177 static base::TimeDelta
unused_idle_socket_timeout();
178 static void set_unused_idle_socket_timeout(base::TimeDelta timeout
);
180 static base::TimeDelta
used_idle_socket_timeout();
181 static void set_used_idle_socket_timeout(base::TimeDelta timeout
);
185 ~ClientSocketPool() override
;
187 // Return the connection timeout for this pool.
188 virtual base::TimeDelta
ConnectionTimeout() const = 0;
191 DISALLOW_COPY_AND_ASSIGN(ClientSocketPool
);
194 template <typename PoolType
>
195 void RequestSocketsForPool(
197 const std::string
& group_name
,
198 const scoped_refptr
<typename
PoolType::SocketParams
>& params
,
200 const BoundNetLog
& net_log
) {
201 pool
->RequestSockets(group_name
, ¶ms
, num_sockets
, net_log
);
206 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_H_