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

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

Issue 62181: Add a bound on the total number of active sockets in ClientSocketPool.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: do a gclient sync to update files Created 11 years, 8 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 | « no previous file | 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>
(...skipping 10 matching lines...) Expand all
21 21
22 // A ClientSocketPool is used to restrict the number of sockets open at a time. 22 // A ClientSocketPool is used to restrict the number of sockets open at a time.
23 // It also maintains a list of idle persistent sockets. 23 // It also maintains a list of idle persistent sockets.
24 // 24 //
25 // The ClientSocketPool allocates scoped_ptr<ClientSocket> objects, but it is 25 // The ClientSocketPool allocates scoped_ptr<ClientSocket> objects, but it is
26 // not responsible for allocating the associated ClientSocket objects. The 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. 27 // consumer must do so if it gets a scoped_ptr<ClientSocket> with a null value.
28 // 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 // Construct a socket pool with the given limits.
32 //
33 // |max_sockets_per_group|:
34 // The total number of active sockets allowed per "group".
35 // (A "group" generally corresponds with a single host, so this is
36 // effectively the connections-per-host bound).
37 //
38 // |max_sockets|:
39 // The total number of active sockets across all groups.
40 //
41 // TODO(eroman): would be nice to define these in terms of "open" sockets
42 // instead (active + idle).
43 ClientSocketPool(int max_sockets_per_group, int max_sockets);
32 44
33 // Called to request a socket for the given handle. There are three possible 45 // Called to request a socket for the given handle. There are three possible
34 // results: 1) the handle will be initialized with a socket to reuse, 2) the 46 // results: 1) the handle will be initialized with a socket to reuse, 2) the
35 // handle will be initialized without a socket such that the consumer needs 47 // handle will be initialized without a socket such that the consumer needs
36 // to supply a socket, or 3) the handle will be added to a wait list until a 48 // to supply a socket, or 3) the handle will be added to a wait list until a
37 // socket is available to reuse or the opportunity to create a new socket 49 // socket is available to reuse or the opportunity to create a new socket
38 // arises. The completion callback is notified in the 3rd case. |priority| 50 // arises. The completion callback is notified in the 3rd case. |priority|
39 // will determine the placement into the wait list. 51 // will determine the placement into the wait list.
40 // 52 //
41 // If this function returns OK, then |handle| is initialized upon return. 53 // If this function returns OK, then |handle| is initialized upon return.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 115
104 typedef std::deque<Request> RequestQueue; 116 typedef std::deque<Request> RequestQueue;
105 117
106 // A Group is allocated per group_name when there are idle sockets or pending 118 // A Group is allocated per group_name when there are idle sockets or pending
107 // requests. Otherwise, the Group object is removed from the map. 119 // requests. Otherwise, the Group object is removed from the map.
108 struct Group { 120 struct Group {
109 Group() : active_socket_count(0) {} 121 Group() : active_socket_count(0) {}
110 std::deque<IdleSocket> idle_sockets; 122 std::deque<IdleSocket> idle_sockets;
111 RequestQueue pending_requests; 123 RequestQueue pending_requests;
112 int active_socket_count; 124 int active_socket_count;
125
126 bool empty() const {
127 return active_socket_count == 0 && idle_sockets.empty() &&
128 pending_requests.empty();
129 }
113 }; 130 };
114 131
115 typedef std::map<std::string, Group> GroupMap; 132 typedef std::map<std::string, Group> GroupMap;
116 133
117 ~ClientSocketPool(); 134 ~ClientSocketPool();
118 135
119 static void InsertRequestIntoQueue(const Request& r, 136 static void InsertRequestIntoQueue(const Request& r,
120 RequestQueue* pending_requests); 137 RequestQueue* pending_requests);
121 138
122 // Closes all idle sockets if |force| is true. Else, only closes idle 139 // Closes all idle sockets if |force| is true. Else, only closes idle
123 // sockets that timed out or can't be reused. 140 // sockets that timed out or can't be reused.
124 void CleanupIdleSockets(bool force); 141 void CleanupIdleSockets(bool force);
125 142
126 // Called when the number of idle sockets changes. 143 // Called when the number of idle sockets changes.
127 void IncrementIdleCount(); 144 void IncrementIdleCount();
128 void DecrementIdleCount(); 145 void DecrementIdleCount();
129 146
130 // Called via PostTask by ReleaseSocket. 147 // Called via PostTask by ReleaseSocket.
131 void DoReleaseSocket(const std::string& group_name, ClientSocketPtr* ptr); 148 void DoReleaseSocket(const std::string& group_name, ClientSocketPtr* ptr);
132 149
150 // Dequeue and start the highest priority pending request in |group|.
151 void StartPendingRequestForGroup(Group* group);
152
153 // Finds the group containing the highest priority pending request, and which
154 // has fewer than |max_sockets_per_group_| active sockets. Returns NULL if
155 // there is no such group.
156 Group* FindTopStalledGroup();
157
158 // Until the maximum number of sockets limit is reached, a group can ONLY
159 // have pending requests if it exceeds the "max sockets per group" limit.
160 //
161 // This means when a socket is released, the only pending requests that can
162 // be started next belong to the same group.
163 //
164 // However once the |max_sockets_| limit is reached, this stops being true:
165 // groups can now have pending requests without having first reached the
166 // |max_sockets_per_group_| limit. So choosing the next request involves
167 // selecting the highest priority request across *all* groups.
168 //
169 // Since reaching the maximum number of sockets is an edge case, we make note
170 // of when it happens with the following variable, and thus avoid doing
171 // the slower "scan all groups" in the common case.
172 bool may_have_stalled_group_;
173
133 // Called when timer_ fires. This method scans the idle sockets removing 174 // Called when timer_ fires. This method scans the idle sockets removing
134 // sockets that timed out or can't be reused. 175 // sockets that timed out or can't be reused.
135 void OnCleanupTimerFired() { 176 void OnCleanupTimerFired() {
136 CleanupIdleSockets(false); 177 CleanupIdleSockets(false);
137 } 178 }
138 179
139 GroupMap group_map_; 180 GroupMap group_map_;
140 181
141 // Timer used to periodically prune idle sockets that timed out or can't be 182 // Timer used to periodically prune idle sockets that timed out or can't be
142 // reused. 183 // reused.
143 base::RepeatingTimer<ClientSocketPool> timer_; 184 base::RepeatingTimer<ClientSocketPool> timer_;
144 185
145 // The total number of idle sockets in the system. 186 // The total number of idle sockets in the system.
146 int idle_socket_count_; 187 int idle_socket_count_;
147 188
148 // The maximum number of sockets kept per group. 189 // The total number of active sockets in the system.
190 int active_socket_count_;
191
192 // The maximum number of active sockets kept per group.
149 int max_sockets_per_group_; 193 int max_sockets_per_group_;
150 194
195 // The maximum number of active sockets kept across all groups.
196 int max_sockets_;
197
151 DISALLOW_COPY_AND_ASSIGN(ClientSocketPool); 198 DISALLOW_COPY_AND_ASSIGN(ClientSocketPool);
152 }; 199 };
153 200
154 } // namespace net 201 } // namespace net
155 202
156 #endif // NET_BASE_CLIENT_SOCKET_POOL_H_ 203 #endif // NET_BASE_CLIENT_SOCKET_POOL_H_
OLDNEW
« no previous file with comments | « no previous file | net/base/client_socket_pool.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698