Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(302)

Side by Side Diff: net/base/tcp_client_socket_pool.h

Issue 144009: Move socket related files from net/base to net/socket. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/tcp_client_socket_libevent.cc ('k') | net/base/tcp_client_socket_pool.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2006-2008 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_BASE_TCP_CLIENT_SOCKET_POOL_H_
6 #define NET_BASE_TCP_CLIENT_SOCKET_POOL_H_
7
8 #include <deque>
9 #include <map>
10 #include <string>
11
12 #include "base/scoped_ptr.h"
13 #include "base/timer.h"
14 #include "net/base/address_list.h"
15 #include "net/base/client_socket_pool.h"
16 #include "net/base/host_resolver.h"
17
18 namespace net {
19
20 class ClientSocketFactory;
21 class ClientSocketPoolBase;
22
23 // ConnectingSocket provides an abstract interface for "connecting" a socket.
24 // The connection may involve host resolution, tcp connection, ssl connection,
25 // etc.
26 class ConnectingSocket {
27 public:
28 ConnectingSocket() {}
29 virtual ~ConnectingSocket() {}
30
31 // Begins connecting the socket. Returns OK on success, ERR_IO_PENDING if it
32 // cannot complete synchronously without blocking, or another net error code
33 // on error.
34 virtual int Connect() = 0;
35
36 private:
37 DISALLOW_COPY_AND_ASSIGN(ConnectingSocket);
38 };
39
40 // TCPConnectingSocket handles the host resolution necessary for socket creation
41 // and the tcp connect.
42 class TCPConnectingSocket : public ConnectingSocket {
43 public:
44 TCPConnectingSocket(const std::string& group_name,
45 const HostResolver::RequestInfo& resolve_info,
46 const ClientSocketHandle* handle,
47 ClientSocketFactory* client_socket_factory,
48 ClientSocketPoolBase* pool);
49 ~TCPConnectingSocket();
50
51 // ConnectingSocket methods.
52
53 // Begins the host resolution and the TCP connect. Returns OK on success
54 // and ERR_IO_PENDING if it cannot immediately service the request.
55 // Otherwise, it returns a net error code.
56 virtual int Connect();
57
58 private:
59 // Handles asynchronous completion of IO. |result| represents the result of
60 // the IO operation.
61 void OnIOComplete(int result);
62
63 // Handles both asynchronous and synchronous completion of IO. |result|
64 // represents the result of the IO operation. |synchronous| indicates
65 // whether or not the previous IO operation completed synchronously or
66 // asynchronously. OnIOCompleteInternal returns the result of the next IO
67 // operation that executes, or just the value of |result|.
68 int OnIOCompleteInternal(int result, bool synchronous);
69
70 const std::string group_name_;
71 const HostResolver::RequestInfo resolve_info_;
72 const ClientSocketHandle* const handle_;
73 ClientSocketFactory* const client_socket_factory_;
74 CompletionCallbackImpl<TCPConnectingSocket> callback_;
75 scoped_ptr<ClientSocket> socket_;
76 ClientSocketPoolBase* const pool_;
77 SingleRequestHostResolver resolver_;
78 AddressList addresses_;
79
80 // The time the Connect() method was called (if it got called).
81 base::TimeTicks connect_start_time_;
82
83 DISALLOW_COPY_AND_ASSIGN(TCPConnectingSocket);
84 };
85
86 // A ClientSocketPoolBase is used to restrict the number of sockets open at
87 // a time. It also maintains a list of idle persistent sockets.
88 //
89 class ClientSocketPoolBase : public base::RefCounted<ClientSocketPoolBase> {
90 public:
91 // A Request is allocated per call to RequestSocket that results in
92 // ERR_IO_PENDING.
93 struct Request {
94 // HostResolver::RequestInfo has no default constructor, so fudge something.
95 Request() : resolve_info(std::string(), 0) {}
96
97 Request(ClientSocketHandle* handle,
98 CompletionCallback* callback,
99 int priority,
100 const HostResolver::RequestInfo& resolve_info,
101 LoadState load_state)
102 : handle(handle), callback(callback), priority(priority),
103 resolve_info(resolve_info), load_state(load_state) {
104 }
105
106 ClientSocketHandle* handle;
107 CompletionCallback* callback;
108 int priority;
109 HostResolver::RequestInfo resolve_info;
110 LoadState load_state;
111 };
112
113 class ConnectingSocketFactory {
114 public:
115 ConnectingSocketFactory() {}
116 virtual ~ConnectingSocketFactory() {}
117
118 virtual ConnectingSocket* NewConnectingSocket(
119 const std::string& group_name,
120 const Request& request,
121 ClientSocketPoolBase* pool) const = 0;
122
123 private:
124 DISALLOW_COPY_AND_ASSIGN(ConnectingSocketFactory);
125 };
126
127 ClientSocketPoolBase(int max_sockets_per_group,
128 HostResolver* host_resolver,
129 ConnectingSocketFactory* connecting_socket_factory);
130
131 ~ClientSocketPoolBase();
132
133 int RequestSocket(const std::string& group_name,
134 const HostResolver::RequestInfo& resolve_info,
135 int priority,
136 ClientSocketHandle* handle,
137 CompletionCallback* callback);
138
139 void CancelRequest(const std::string& group_name,
140 const ClientSocketHandle* handle);
141
142 void ReleaseSocket(const std::string& group_name,
143 ClientSocket* socket);
144
145 void CloseIdleSockets();
146
147 HostResolver* GetHostResolver() const {
148 return host_resolver_;
149 }
150
151 int idle_socket_count() const {
152 return idle_socket_count_;
153 }
154
155 int IdleSocketCountInGroup(const std::string& group_name) const;
156
157 LoadState GetLoadState(const std::string& group_name,
158 const ClientSocketHandle* handle) const;
159
160 // Used by ConnectingSocket until we remove the coupling between a specific
161 // ConnectingSocket and a ClientSocketHandle:
162
163 // Returns NULL if not found. Otherwise it returns the Request*
164 // corresponding to the ConnectingSocket (keyed by |group_name| and |handle|.
165 // Note that this pointer may be invalidated after any call that might mutate
166 // the RequestMap or GroupMap, so the user should not hold onto the pointer
167 // for long.
168 Request* GetConnectingRequest(const std::string& group_name,
169 const ClientSocketHandle* handle);
170
171 // Handles the completed Request corresponding to the ConnectingSocket (keyed
172 // by |group_name| and |handle|. |deactivate| indicates whether or not to
173 // deactivate the socket, making the socket slot available for a new socket
174 // connection. If |deactivate| is false, then set |socket| into |handle|.
175 // Returns the callback to run.
176 CompletionCallback* OnConnectingRequestComplete(
177 const std::string& group_name,
178 const ClientSocketHandle* handle,
179 bool deactivate,
180 ClientSocket* socket);
181
182 private:
183 // Entry for a persistent socket which became idle at time |start_time|.
184 struct IdleSocket {
185 ClientSocket* socket;
186 base::TimeTicks start_time;
187
188 // An idle socket should be removed if it can't be reused, or has been idle
189 // for too long. |now| is the current time value (TimeTicks::Now()).
190 //
191 // An idle socket can't be reused if it is disconnected or has received
192 // data unexpectedly (hence no longer idle). The unread data would be
193 // mistaken for the beginning of the next response if we were to reuse the
194 // socket for a new request.
195 bool ShouldCleanup(base::TimeTicks now) const;
196 };
197
198 typedef std::deque<Request> RequestQueue;
199 typedef std::map<const ClientSocketHandle*, Request> RequestMap;
200
201 // A Group is allocated per group_name when there are idle sockets or pending
202 // requests. Otherwise, the Group object is removed from the map.
203 struct Group {
204 Group() : active_socket_count(0), sockets_handed_out_count(0) {}
205 std::deque<IdleSocket> idle_sockets;
206 RequestQueue pending_requests;
207 RequestMap connecting_requests;
208 int active_socket_count; // number of active sockets
209 int sockets_handed_out_count; // number of sockets given to clients
210 };
211
212 typedef std::map<std::string, Group> GroupMap;
213
214 typedef std::map<const ClientSocketHandle*, ConnectingSocket*>
215 ConnectingSocketMap;
216
217 static void InsertRequestIntoQueue(const Request& r,
218 RequestQueue* pending_requests);
219
220 // Closes all idle sockets if |force| is true. Else, only closes idle
221 // sockets that timed out or can't be reused.
222 void CleanupIdleSockets(bool force);
223
224 // Called when the number of idle sockets changes.
225 void IncrementIdleCount();
226 void DecrementIdleCount();
227
228 // Called via PostTask by ReleaseSocket.
229 void DoReleaseSocket(const std::string& group_name, ClientSocket* socket);
230
231 // Called when timer_ fires. This method scans the idle sockets removing
232 // sockets that timed out or can't be reused.
233 void OnCleanupTimerFired() {
234 CleanupIdleSockets(false);
235 }
236
237 // Removes the ConnectingSocket corresponding to |handle| from the
238 // |connecting_socket_map_|.
239 void RemoveConnectingSocket(const ClientSocketHandle* handle);
240
241 static void CheckSocketCounts(const Group& group);
242
243 // Process a request from a group's pending_requests queue.
244 void ProcessPendingRequest(const std::string& group_name, Group* group);
245
246 GroupMap group_map_;
247
248 ConnectingSocketMap connecting_socket_map_;
249
250 // Timer used to periodically prune idle sockets that timed out or can't be
251 // reused.
252 base::RepeatingTimer<ClientSocketPoolBase> timer_;
253
254 // The total number of idle sockets in the system.
255 int idle_socket_count_;
256
257 // The maximum number of sockets kept per group.
258 const int max_sockets_per_group_;
259
260 // The host resolver that will be used to do DNS lookups for connecting
261 // sockets.
262 HostResolver* const host_resolver_;
263
264 scoped_ptr<ConnectingSocketFactory> connecting_socket_factory_;
265
266 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase);
267 };
268
269 class TCPClientSocketPool : public ClientSocketPool {
270 public:
271 TCPClientSocketPool(int max_sockets_per_group,
272 HostResolver* host_resolver,
273 ClientSocketFactory* client_socket_factory);
274
275 // ClientSocketPool methods:
276
277 virtual int RequestSocket(const std::string& group_name,
278 const HostResolver::RequestInfo& resolve_info,
279 int priority,
280 ClientSocketHandle* handle,
281 CompletionCallback* callback);
282
283 virtual void CancelRequest(const std::string& group_name,
284 const ClientSocketHandle* handle);
285
286 virtual void ReleaseSocket(const std::string& group_name,
287 ClientSocket* socket);
288
289 virtual void CloseIdleSockets();
290
291 virtual HostResolver* GetHostResolver() const {
292 return base_->GetHostResolver();
293 }
294
295 virtual int IdleSocketCount() const {
296 return base_->idle_socket_count();
297 }
298
299 virtual int IdleSocketCountInGroup(const std::string& group_name) const;
300
301 virtual LoadState GetLoadState(const std::string& group_name,
302 const ClientSocketHandle* handle) const;
303
304 private:
305 virtual ~TCPClientSocketPool();
306
307 class TCPConnectingSocketFactory
308 : public ClientSocketPoolBase::ConnectingSocketFactory {
309 public:
310 TCPConnectingSocketFactory(ClientSocketFactory* client_socket_factory)
311 : client_socket_factory_(client_socket_factory) {}
312
313 virtual ~TCPConnectingSocketFactory() {}
314
315 // ClientSocketPoolBase::ConnectingSocketFactory methods.
316
317 virtual ConnectingSocket* NewConnectingSocket(
318 const std::string& group_name,
319 const ClientSocketPoolBase::Request& request,
320 ClientSocketPoolBase* pool) const;
321
322 private:
323 ClientSocketFactory* const client_socket_factory_;
324
325 DISALLOW_COPY_AND_ASSIGN(TCPConnectingSocketFactory);
326 };
327
328 // One might ask why ClientSocketPoolBase is also refcounted if its
329 // containing ClientSocketPool is already refcounted. The reason is because
330 // DoReleaseSocket() posts a task. If ClientSocketPool gets deleted between
331 // the posting of the task and the execution, then we'll hit the DCHECK that
332 // |ClientSocketPoolBase::group_map_| is empty.
333 scoped_refptr<ClientSocketPoolBase> base_;
334
335 DISALLOW_COPY_AND_ASSIGN(TCPClientSocketPool);
336 };
337
338 } // namespace net
339
340 #endif // NET_BASE_TCP_CLIENT_SOCKET_POOL_H_
OLDNEW
« no previous file with comments | « net/base/tcp_client_socket_libevent.cc ('k') | net/base/tcp_client_socket_pool.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698