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

Side by Side Diff: net/socket/client_socket_pool_base.h

Issue 151118: Refactor ConnectJob and TCPConnectJob. (Closed)
Patch Set: Add comments. Created 11 years, 5 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 | « no previous file | net/socket/client_socket_pool_base.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_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ 5 #ifndef NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_
6 #define NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ 6 #define NET_SOCKET_CLIENT_SOCKET_POOL_BASE_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/basictypes.h" 12 #include "base/basictypes.h"
13 #include "base/scoped_ptr.h" 13 #include "base/scoped_ptr.h"
14 #include "base/time.h" 14 #include "base/time.h"
15 #include "base/timer.h" 15 #include "base/timer.h"
16 #include "net/base/address_list.h" 16 #include "net/base/address_list.h"
17 #include "net/base/completion_callback.h" 17 #include "net/base/completion_callback.h"
18 #include "net/base/host_resolver.h" 18 #include "net/base/host_resolver.h"
19 #include "net/base/load_states.h" 19 #include "net/base/load_states.h"
20 #include "net/socket/client_socket.h"
20 #include "net/socket/client_socket_pool.h" 21 #include "net/socket/client_socket_pool.h"
21 22
22 namespace net { 23 namespace net {
23 24
24 class ClientSocket;
25 class ClientSocketHandle; 25 class ClientSocketHandle;
26 class ClientSocketPoolBase; 26 class ClientSocketPoolBase;
27 27
28 // ConnectJob provides an abstract interface for "connecting" a socket. 28 // ConnectJob provides an abstract interface for "connecting" a socket.
29 // The connection may involve host resolution, tcp connection, ssl connection, 29 // The connection may involve host resolution, tcp connection, ssl connection,
30 // etc. 30 // etc.
31 class ConnectJob { 31 class ConnectJob {
32 public: 32 public:
33 class Delegate { 33 class Delegate {
34 public: 34 public:
35 Delegate() {} 35 Delegate() {}
36 virtual ~Delegate() {} 36 virtual ~Delegate() {}
37 37
38 // Alerts the delegate that the connection completed (though not necessarily 38 // Alerts the delegate that the connection completed.
39 // successfully). |group_name| indicates the connection group this 39 virtual void OnConnectJobComplete(int result, ConnectJob* job) = 0;
40 // ConnectJob corresponds to. |key_handle| uniquely identifies the
41 // ClientSocketHandle that this job is coupled to. |socket| is non-NULL if
42 // the connection completed successfully, and ownership is transferred to
43 // the delegate. |was_async| indicates whether or not the connect job
44 // completed asynchronously.
45 virtual void OnConnectJobComplete(
46 const std::string& group_name,
47 const ClientSocketHandle* key_handle,
48 ClientSocket* socket,
49 int result,
50 bool was_async) = 0;
51 40
52 private: 41 private:
53 DISALLOW_COPY_AND_ASSIGN(Delegate); 42 DISALLOW_COPY_AND_ASSIGN(Delegate);
54 }; 43 };
55 44
56 ConnectJob() {} 45 ConnectJob(const std::string& group_name,
57 virtual ~ConnectJob() {} 46 const ClientSocketHandle* key_handle,
47 Delegate* delegate);
48 virtual ~ConnectJob();
58 49
59 // Returns the LoadState of this ConnectJob. 50 // Accessors
51 const std::string& group_name() const { return group_name_; }
60 LoadState load_state() const { return load_state_; } 52 LoadState load_state() const { return load_state_; }
53 const ClientSocketHandle* key_handle() const { return key_handle_; }
54
55 // Releases |socket_| to the client.
56 ClientSocket* ReleaseSocket() { return socket_.release(); }
61 57
62 // Begins connecting the socket. Returns OK on success, ERR_IO_PENDING if it 58 // Begins connecting the socket. Returns OK on success, ERR_IO_PENDING if it
63 // cannot complete synchronously without blocking, or another net error code 59 // cannot complete synchronously without blocking, or another net error code
64 // on error. 60 // on error. In asynchronous completion, the ConnectJob will notify
61 // |delegate_| via OnConnectJobComplete. In both asynchronous and synchronous
62 // completion, ReleaseSocket() can be called to acquire the connected socket
63 // if it succeeded.
65 virtual int Connect() = 0; 64 virtual int Connect() = 0;
66 65
67 protected: 66 protected:
68 void set_load_state(LoadState load_state) { load_state_ = load_state; } 67 void set_load_state(LoadState load_state) { load_state_ = load_state; }
68 void set_socket(ClientSocket* socket) { socket_.reset(socket); }
69 ClientSocket* socket() { return socket_.get(); }
70 Delegate* delegate() { return delegate_; }
69 71
70 private: 72 private:
73 const std::string group_name_;
74 // Temporarily needed until we switch to late binding.
75 const ClientSocketHandle* const key_handle_;
76 Delegate* const delegate_;
71 LoadState load_state_; 77 LoadState load_state_;
78 scoped_ptr<ClientSocket> socket_;
72 79
73 DISALLOW_COPY_AND_ASSIGN(ConnectJob); 80 DISALLOW_COPY_AND_ASSIGN(ConnectJob);
74 }; 81 };
75 82
76 // A ClientSocketPoolBase is used to restrict the number of sockets open at 83 // A ClientSocketPoolBase is used to restrict the number of sockets open at
77 // a time. It also maintains a list of idle persistent sockets. 84 // a time. It also maintains a list of idle persistent sockets.
78 // 85 //
79 class ClientSocketPoolBase 86 class ClientSocketPoolBase
80 : public base::RefCounted<ClientSocketPoolBase>, 87 : public base::RefCounted<ClientSocketPoolBase>,
81 public ConnectJob::Delegate { 88 public ConnectJob::Delegate {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 142
136 int idle_socket_count() const { 143 int idle_socket_count() const {
137 return idle_socket_count_; 144 return idle_socket_count_;
138 } 145 }
139 146
140 int IdleSocketCountInGroup(const std::string& group_name) const; 147 int IdleSocketCountInGroup(const std::string& group_name) const;
141 148
142 LoadState GetLoadState(const std::string& group_name, 149 LoadState GetLoadState(const std::string& group_name,
143 const ClientSocketHandle* handle) const; 150 const ClientSocketHandle* handle) const;
144 151
145 // If |was_async| is true, then ClientSocketPoolBase will pick a callback to 152 virtual void OnConnectJobComplete(int result, ConnectJob* job);
146 // run from a request associated with |group_name|.
147 virtual void OnConnectJobComplete(
148 const std::string& group_name,
149 const ClientSocketHandle* key_handle,
150 ClientSocket* socket,
151 int result,
152 bool was_async);
153 153
154 private: 154 private:
155 // Entry for a persistent socket which became idle at time |start_time|. 155 // Entry for a persistent socket which became idle at time |start_time|.
156 struct IdleSocket { 156 struct IdleSocket {
157 ClientSocket* socket; 157 ClientSocket* socket;
158 base::TimeTicks start_time; 158 base::TimeTicks start_time;
159 159
160 // An idle socket should be removed if it can't be reused, or has been idle 160 // An idle socket should be removed if it can't be reused, or has been idle
161 // for too long. |now| is the current time value (TimeTicks::Now()). 161 // for too long. |now| is the current time value (TimeTicks::Now()).
162 // 162 //
163 // An idle socket can't be reused if it is disconnected or has received 163 // An idle socket can't be reused if it is disconnected or has received
164 // data unexpectedly (hence no longer idle). The unread data would be 164 // data unexpectedly (hence no longer idle). The unread data would be
165 // mistaken for the beginning of the next response if we were to reuse the 165 // mistaken for the beginning of the next response if we were to reuse the
166 // socket for a new request. 166 // socket for a new request.
167 bool ShouldCleanup(base::TimeTicks now) const; 167 bool ShouldCleanup(base::TimeTicks now) const;
168 }; 168 };
169 169
170 typedef std::deque<Request> RequestQueue; 170 typedef std::deque<Request> RequestQueue;
171 typedef std::map<const ClientSocketHandle*, Request> RequestMap; 171 typedef std::map<const ClientSocketHandle*, Request> RequestMap;
172 172
173 // A Group is allocated per group_name when there are idle sockets or pending 173 // A Group is allocated per group_name when there are idle sockets or pending
174 // requests. Otherwise, the Group object is removed from the map. 174 // requests. Otherwise, the Group object is removed from the map.
175 struct Group { 175 struct Group {
176 Group() : active_socket_count(0), sockets_handed_out_count(0) {} 176 Group() : active_socket_count(0) {}
177
178 bool IsEmpty() const {
179 return active_socket_count == 0 && idle_sockets.empty() &&
180 connecting_requests.empty();
181 }
182
183 bool HasAvailableSocketSlot(int max_sockets_per_group) const {
184 return active_socket_count +
185 static_cast<int>(connecting_requests.size()) <
186 max_sockets_per_group;
187 }
188
177 std::deque<IdleSocket> idle_sockets; 189 std::deque<IdleSocket> idle_sockets;
178 RequestQueue pending_requests; 190 RequestQueue pending_requests;
179 RequestMap connecting_requests; 191 RequestMap connecting_requests;
180 int active_socket_count; // number of active sockets 192 int active_socket_count; // number of active sockets used by clients
181 int sockets_handed_out_count; // number of sockets given to clients
182 }; 193 };
183 194
184 typedef std::map<std::string, Group> GroupMap; 195 typedef std::map<std::string, Group> GroupMap;
185 196
186 typedef std::map<const ClientSocketHandle*, ConnectJob*> ConnectJobMap; 197 typedef std::map<const ClientSocketHandle*, ConnectJob*> ConnectJobMap;
187 198
188 static void InsertRequestIntoQueue(const Request& r, 199 static void InsertRequestIntoQueue(const Request& r,
189 RequestQueue* pending_requests); 200 RequestQueue* pending_requests);
190 201
191 // Closes all idle sockets if |force| is true. Else, only closes idle 202 // Closes all idle sockets if |force| is true. Else, only closes idle
(...skipping 10 matching lines...) Expand all
202 // Called when timer_ fires. This method scans the idle sockets removing 213 // Called when timer_ fires. This method scans the idle sockets removing
203 // sockets that timed out or can't be reused. 214 // sockets that timed out or can't be reused.
204 void OnCleanupTimerFired() { 215 void OnCleanupTimerFired() {
205 CleanupIdleSockets(false); 216 CleanupIdleSockets(false);
206 } 217 }
207 218
208 // Removes the ConnectJob corresponding to |handle| from the 219 // Removes the ConnectJob corresponding to |handle| from the
209 // |connect_job_map_|. 220 // |connect_job_map_|.
210 void RemoveConnectJob(const ClientSocketHandle* handle); 221 void RemoveConnectJob(const ClientSocketHandle* handle);
211 222
212 static void CheckSocketCounts(const Group& group); 223 // Same as OnAvailableSocketSlot except it looks up the Group first to see if
224 // it's there.
225 void MaybeOnAvailableSocketSlot(const std::string& group_name);
213 226
214 // Remove an active socket. 227 // Might delete the Group from |group_map_|.
215 void RemoveActiveSocket(const std::string& group_name, Group* group); 228 void OnAvailableSocketSlot(const std::string& group_name, Group* group);
216 229
217 // Process a request from a group's pending_requests queue. 230 // Process a request from a group's pending_requests queue.
218 void ProcessPendingRequest(const std::string& group_name, Group* group); 231 void ProcessPendingRequest(const std::string& group_name, Group* group);
219 232
233 // Assigns |socket| to |handle| and updates |group|'s counters appropriately.
234 void HandOutSocket(ClientSocket* socket,
235 bool reused,
236 ClientSocketHandle* handle,
237 Group* group);
238
220 GroupMap group_map_; 239 GroupMap group_map_;
221 240
222 ConnectJobMap connect_job_map_; 241 ConnectJobMap connect_job_map_;
223 242
224 // Timer used to periodically prune idle sockets that timed out or can't be 243 // Timer used to periodically prune idle sockets that timed out or can't be
225 // reused. 244 // reused.
226 base::RepeatingTimer<ClientSocketPoolBase> timer_; 245 base::RepeatingTimer<ClientSocketPoolBase> timer_;
227 246
228 // The total number of idle sockets in the system. 247 // The total number of idle sockets in the system.
229 int idle_socket_count_; 248 int idle_socket_count_;
230 249
231 // The maximum number of sockets kept per group. 250 // The maximum number of sockets kept per group.
232 const int max_sockets_per_group_; 251 const int max_sockets_per_group_;
233 252
234 const scoped_ptr<ConnectJobFactory> connect_job_factory_; 253 const scoped_ptr<ConnectJobFactory> connect_job_factory_;
235 254
236 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase); 255 DISALLOW_COPY_AND_ASSIGN(ClientSocketPoolBase);
237 }; 256 };
238 257
239 } // namespace net 258 } // namespace net
240 259
241 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_ 260 #endif // NET_SOCKET_CLIENT_SOCKET_POOL_BASE_H_
OLDNEW
« no previous file with comments | « no previous file | net/socket/client_socket_pool_base.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698