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

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

Issue 118219: Reland my ClientSocketPool refactor again... (Closed)
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
« no previous file with comments | « net/base/client_socket_handle.cc ('k') | net/base/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
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef NET_BASE_CLIENT_SOCKET_POOL_H_ 5 #ifndef NET_BASE_CLIENT_SOCKET_POOL_H_
6 #define NET_BASE_CLIENT_SOCKET_POOL_H_ 6 #define NET_BASE_CLIENT_SOCKET_POOL_H_
7 7
8 #include <deque> 8 #include <deque>
9 #include <map> 9 #include <map>
10 #include <string> 10 #include <string>
11 11
12 #include "base/ref_counted.h" 12 #include "base/ref_counted.h"
13 #include "base/scoped_ptr.h" 13 #include "base/scoped_ptr.h"
14 #include "base/timer.h" 14 #include "base/timer.h"
15 #include "net/base/address_list.h"
15 #include "net/base/completion_callback.h" 16 #include "net/base/completion_callback.h"
17 #include "net/base/host_resolver.h"
18 #include "net/base/load_states.h"
16 19
17 namespace net { 20 namespace net {
18 21
19 class ClientSocket; 22 class ClientSocket;
23 class ClientSocketFactory;
20 class ClientSocketHandle; 24 class ClientSocketHandle;
21 25
22 // A ClientSocketPool is used to restrict the number of sockets open at a time. 26 // A ClientSocketPool is used to restrict the number of sockets open at a time.
23 // It also maintains a list of idle persistent sockets. 27 // It also maintains a list of idle persistent sockets.
24 // 28 //
25 // The ClientSocketPool allocates scoped_ptr<ClientSocket> objects, but it is
26 // not responsible for allocating the associated ClientSocket objects. The
27 // consumer must do so if it gets a scoped_ptr<ClientSocket> with a null value.
28 //
29 class ClientSocketPool : public base::RefCounted<ClientSocketPool> { 29 class ClientSocketPool : public base::RefCounted<ClientSocketPool> {
30 public: 30 public:
31 explicit ClientSocketPool(int max_sockets_per_group); 31 ClientSocketPool(int max_sockets_per_group,
32 ClientSocketFactory* client_socket_factory);
32 33
33 // Called to request a socket for the given handle. There are three possible 34 // Requests a connected socket for a group_name.
34 // results: 1) the handle will be initialized with a socket to reuse, 2) the 35 //
35 // handle will be initialized without a socket such that the consumer needs 36 // There are four possible results from calling this function:
36 // to supply a socket, or 3) the handle will be added to a wait list until a 37 // 1) RequestSocket returns OK and initializes |handle| with a reused socket.
37 // socket is available to reuse or the opportunity to create a new socket 38 // 2) RequestSocket returns OK with a newly connected socket.
38 // arises. The completion callback is notified in the 3rd case. |priority| 39 // 3) RequestSocket returns ERR_IO_PENDING. The handle will be added to a
39 // will determine the placement into the wait list. 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.
40 // 43 //
41 // If this function returns OK, then |handle| is initialized upon return. 44 // If this function returns OK, then |handle| is initialized upon return.
42 // The |handle|'s is_initialized method will return true in this case. If a 45 // The |handle|'s is_initialized method will return true in this case. If a
43 // ClientSocket was reused, then |handle|'s socket member will be non-NULL. 46 // ClientSocket was reused, then ClientSocketPool will call
44 // Otherwise, the consumer will need to supply |handle| with a socket by 47 // |handle|->set_reused(true). In either case, the socket will have been
45 // allocating a new ClientSocket object and calling the |handle|'s set_socket 48 // allocated and will be connected. A client might want to know whether or
46 // method. 49 // not the socket is reused in order to know whether or not he needs to
50 // perform SSL connection or tunnel setup or to request a new socket if he
51 // encounters an error with the reused socket.
47 // 52 //
48 // If ERR_IO_PENDING is returned, then the completion callback will be called 53 // If ERR_IO_PENDING is returned, then the callback will be used to notify the
49 // when |handle| has been initialized. 54 // client of completion.
50 // 55 //
51 int RequestSocket(ClientSocketHandle* handle, 56 int RequestSocket(const std::string& group_name,
57 const std::string& host,
58 int port,
52 int priority, 59 int priority,
60 ClientSocketHandle* handle,
53 CompletionCallback* callback); 61 CompletionCallback* callback);
54 62
55 // Called to cancel a RequestSocket call that returned ERR_IO_PENDING. The 63 // Called to cancel a RequestSocket call that returned ERR_IO_PENDING. The
56 // same handle parameter must be passed to this method as was passed to the 64 // same handle parameter must be passed to this method as was passed to the
57 // RequestSocket call being cancelled. The associated CompletionCallback is 65 // RequestSocket call being cancelled. The associated CompletionCallback is
58 // not run. 66 // not run.
59 void CancelRequest(ClientSocketHandle* handle); 67 void CancelRequest(const std::string& group_name,
68 const ClientSocketHandle* handle);
60 69
61 // Called to release the socket member of an initialized ClientSocketHandle 70 // Called to release a socket once the socket is no longer needed. If the
62 // once the socket is no longer needed. If the socket member is non-null and 71 // socket still has an established connection, then it will be added to the
63 // still has an established connection, then it will be added to the idle set 72 // set of idle sockets to be used to satisfy future RequestSocket calls.
64 // of sockets to be used to satisfy future RequestSocket calls. Otherwise, 73 // Otherwise, the ClientSocket is destroyed.
65 // the ClientSocket is destroyed. 74 void ReleaseSocket(const std::string& group_name, ClientSocket* socket);
66 void ReleaseSocket(ClientSocketHandle* handle);
67 75
68 // Called to close any idle connections held by the connection manager. 76 // Called to close any idle connections held by the connection manager.
69 void CloseIdleSockets(); 77 void CloseIdleSockets();
70 78
71 // The total number of idle sockets in the pool. 79 // The total number of idle sockets in the pool.
72 int idle_socket_count() const { 80 int idle_socket_count() const {
73 return idle_socket_count_; 81 return idle_socket_count_;
74 } 82 }
75 83
76 // The total number of idle sockets in a connection group. 84 // The total number of idle sockets in a connection group.
77 int IdleSocketCountInGroup(const std::string& group_name) const; 85 int IdleSocketCountInGroup(const std::string& group_name) const;
78 86
87 // Determine the LoadState of a connecting ClientSocketHandle.
88 LoadState GetLoadState(const std::string& group_name,
89 const ClientSocketHandle* handle) const;
90
79 private: 91 private:
80 friend class base::RefCounted<ClientSocketPool>; 92 friend class base::RefCounted<ClientSocketPool>;
81 93
82 typedef scoped_ptr<ClientSocket> ClientSocketPtr;
83
84 // A Request is allocated per call to RequestSocket that results in 94 // A Request is allocated per call to RequestSocket that results in
85 // ERR_IO_PENDING. 95 // ERR_IO_PENDING.
86 struct Request { 96 struct Request {
87 ClientSocketHandle* handle; 97 ClientSocketHandle* handle;
88 CompletionCallback* callback; 98 CompletionCallback* callback;
89 int priority; 99 int priority;
100 std::string host;
101 int port;
102 LoadState load_state;
90 }; 103 };
91 104
92 // Entry for a persistent socket which became idle at time |start_time|. 105 // Entry for a persistent socket which became idle at time |start_time|.
93 struct IdleSocket { 106 struct IdleSocket {
94 ClientSocketPtr* ptr; 107 ClientSocket* socket;
95 base::TimeTicks start_time; 108 base::TimeTicks start_time;
96 109
97 // An idle socket should be removed if it can't be reused, or has been idle 110 // An idle socket should be removed if it can't be reused, or has been idle
98 // for too long. |now| is the current time value (TimeTicks::Now()). 111 // for too long. |now| is the current time value (TimeTicks::Now()).
99 // 112 //
100 // An idle socket can't be reused if it is disconnected or has received 113 // An idle socket can't be reused if it is disconnected or has received
101 // data unexpectedly (hence no longer idle). The unread data would be 114 // data unexpectedly (hence no longer idle). The unread data would be
102 // mistaken for the beginning of the next response if we were to reuse the 115 // mistaken for the beginning of the next response if we were to reuse the
103 // socket for a new request. 116 // socket for a new request.
104 bool ShouldCleanup(base::TimeTicks now) const; 117 bool ShouldCleanup(base::TimeTicks now) const;
105 }; 118 };
106 119
107 typedef std::deque<Request> RequestQueue; 120 typedef std::deque<Request> RequestQueue;
121 typedef std::map<const ClientSocketHandle*, Request> RequestMap;
108 122
109 // A Group is allocated per group_name when there are idle sockets or pending 123 // A Group is allocated per group_name when there are idle sockets or pending
110 // requests. Otherwise, the Group object is removed from the map. 124 // requests. Otherwise, the Group object is removed from the map.
111 struct Group { 125 struct Group {
112 Group() : active_socket_count(0) {} 126 Group() : active_socket_count(0) {}
113 std::deque<IdleSocket> idle_sockets; 127 std::deque<IdleSocket> idle_sockets;
114 RequestQueue pending_requests; 128 RequestQueue pending_requests;
129 RequestMap connecting_requests;
115 int active_socket_count; 130 int active_socket_count;
116 }; 131 };
117 132
118 typedef std::map<std::string, Group> GroupMap; 133 typedef std::map<std::string, Group> GroupMap;
119 134
135 // ConnectingSocket handles the host resolution necessary for socket creation
136 // and the Connect().
137 class ConnectingSocket {
138 public:
139 enum State {
140 STATE_RESOLVE_HOST,
141 STATE_CONNECT
142 };
143
144 ConnectingSocket(const std::string& group_name,
145 const ClientSocketHandle* handle,
146 ClientSocketFactory* client_socket_factory,
147 ClientSocketPool* pool);
148 ~ConnectingSocket();
149
150 // Begins the host resolution and the TCP connect. Returns OK on success,
151 // in which case |callback| is not called. On pending IO, Connect returns
152 // ERR_IO_PENDING and runs |callback| on completion.
153 int Connect(const std::string& host,
154 int port,
155 CompletionCallback* callback);
156
157 // If Connect() returns OK, ClientSocketPool may invoke this method to get
158 // the ConnectingSocket to release |socket_| to be set into the
159 // ClientSocketHandle immediately.
160 ClientSocket* ReleaseSocket();
161
162 // Called by the ClientSocketPool to cancel this ConnectingSocket. Only
163 // necessary if a ClientSocketHandle is reused.
164 void Cancel();
165
166 private:
167 void OnIOComplete(int result);
168
169 const std::string group_name_;
170 const ClientSocketHandle* const handle_;
171 ClientSocketFactory* const client_socket_factory_;
172 CompletionCallbackImpl<ConnectingSocket> callback_;
173 scoped_ptr<ClientSocket> socket_;
174 scoped_refptr<ClientSocketPool> pool_;
175 HostResolver resolver_;
176 AddressList addresses_;
177 bool canceled_;
178
179 // The time the Connect() method was called (if it got called).
180 base::Time connect_start_time_;
181
182 DISALLOW_COPY_AND_ASSIGN(ConnectingSocket);
183 };
184
120 ~ClientSocketPool(); 185 ~ClientSocketPool();
121 186
122 static void InsertRequestIntoQueue(const Request& r, 187 static void InsertRequestIntoQueue(const Request& r,
123 RequestQueue* pending_requests); 188 RequestQueue* pending_requests);
124 189
125 // Closes all idle sockets if |force| is true. Else, only closes idle 190 // Closes all idle sockets if |force| is true. Else, only closes idle
126 // sockets that timed out or can't be reused. 191 // sockets that timed out or can't be reused.
127 void CleanupIdleSockets(bool force); 192 void CleanupIdleSockets(bool force);
128 193
129 // Called when the number of idle sockets changes. 194 // Called when the number of idle sockets changes.
130 void IncrementIdleCount(); 195 void IncrementIdleCount();
131 void DecrementIdleCount(); 196 void DecrementIdleCount();
132 197
133 // Called via PostTask by ReleaseSocket. 198 // Called via PostTask by ReleaseSocket.
134 void DoReleaseSocket(const std::string& group_name, ClientSocketPtr* ptr); 199 void DoReleaseSocket(const std::string& group_name, ClientSocket* socket);
135 200
136 // Called when timer_ fires. This method scans the idle sockets removing 201 // Called when timer_ fires. This method scans the idle sockets removing
137 // sockets that timed out or can't be reused. 202 // sockets that timed out or can't be reused.
138 void OnCleanupTimerFired() { 203 void OnCleanupTimerFired() {
139 CleanupIdleSockets(false); 204 CleanupIdleSockets(false);
140 } 205 }
141 206
207 ClientSocketFactory* const client_socket_factory_;
208
142 GroupMap group_map_; 209 GroupMap group_map_;
143 210
211 std::map<const ClientSocketHandle*, ConnectingSocket*> connecting_socket_map_;
212
144 // Timer used to periodically prune idle sockets that timed out or can't be 213 // Timer used to periodically prune idle sockets that timed out or can't be
145 // reused. 214 // reused.
146 base::RepeatingTimer<ClientSocketPool> timer_; 215 base::RepeatingTimer<ClientSocketPool> timer_;
147 216
148 // The total number of idle sockets in the system. 217 // The total number of idle sockets in the system.
149 int idle_socket_count_; 218 int idle_socket_count_;
150 219
151 // The maximum number of sockets kept per group. 220 // The maximum number of sockets kept per group.
152 int max_sockets_per_group_; 221 const int max_sockets_per_group_;
153 222
154 DISALLOW_COPY_AND_ASSIGN(ClientSocketPool); 223 DISALLOW_COPY_AND_ASSIGN(ClientSocketPool);
155 }; 224 };
156 225
157 } // namespace net 226 } // namespace net
158 227
159 #endif // NET_BASE_CLIENT_SOCKET_POOL_H_ 228 #endif // NET_BASE_CLIENT_SOCKET_POOL_H_
OLDNEW
« no previous file with comments | « net/base/client_socket_handle.cc ('k') | net/base/client_socket_pool.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698