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

Unified Diff: net/base/client_socket_pool.cc

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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/base/client_socket_pool.h ('k') | net/http/http_network_session.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/base/client_socket_pool.cc
===================================================================
--- net/base/client_socket_pool.cc (revision 14127)
+++ net/base/client_socket_pool.cc (working copy)
@@ -28,9 +28,13 @@
namespace net {
-ClientSocketPool::ClientSocketPool(int max_sockets_per_group)
+ClientSocketPool::ClientSocketPool(int max_sockets_per_group, int max_sockets)
: idle_socket_count_(0),
- max_sockets_per_group_(max_sockets_per_group) {
+ active_socket_count_(0),
+ max_sockets_per_group_(max_sockets_per_group),
+ max_sockets_(max_sockets),
+ may_have_stalled_group_(false) {
+ DCHECK(max_sockets_per_group <= max_sockets);
}
ClientSocketPool::~ClientSocketPool() {
@@ -60,7 +64,9 @@
Group& group = group_map_[handle->group_name_];
// Can we make another active socket now?
- if (group.active_socket_count == max_sockets_per_group_) {
+ bool has_max_sockets = (active_socket_count_ == max_sockets_);
+ if (group.active_socket_count == max_sockets_per_group_ || has_max_sockets) {
+ may_have_stalled_group_ |= has_max_sockets;
Request r;
r.handle = handle;
DCHECK(callback);
@@ -72,6 +78,7 @@
// OK, we are going to activate one.
group.active_socket_count++;
+ active_socket_count_++;
// Use idle sockets in LIFO order because they're more likely to be
// still reusable.
@@ -92,13 +99,10 @@
}
void ClientSocketPool::CancelRequest(ClientSocketHandle* handle) {
- Group& group = group_map_[handle->group_name_];
+ GroupMap::iterator i = group_map_.find(handle->group_name_);
+ DCHECK(i != group_map_.end());
+ Group& group = i->second;
- // In order for us to be canceling a pending request, we must have active
- // sockets equaling the limit. NOTE: The correctness of the code doesn't
- // require this assertion.
- DCHECK(group.active_socket_count == max_sockets_per_group_);
-
// Search pending_requests for matching handle.
std::deque<Request>::iterator it = group.pending_requests.begin();
for (; it != group.pending_requests.end(); ++it) {
@@ -107,6 +111,10 @@
break;
}
}
+
+ // Delete group if no longer needed.
+ if (group.empty())
+ group_map_.erase(i);
}
void ClientSocketPool::ReleaseSocket(ClientSocketHandle* handle) {
@@ -152,8 +160,7 @@
}
// Delete group if no longer needed.
- if (group.active_socket_count == 0 && group.idle_sockets.empty()) {
- DCHECK(group.pending_requests.empty());
+ if (group.empty()) {
group_map_.erase(i++);
} else {
++i;
@@ -180,7 +187,10 @@
Group& group = i->second;
DCHECK(group.active_socket_count > 0);
+ DCHECK(active_socket_count_ > 0);
+
group.active_socket_count--;
+ active_socket_count_--;
bool can_reuse = ptr->get() && (*ptr)->IsConnectedAndIdle();
if (can_reuse) {
@@ -195,20 +205,50 @@
}
// Process one pending request.
- if (!group.pending_requests.empty()) {
- Request r = group.pending_requests.front();
- group.pending_requests.pop_front();
- int rv = RequestSocket(r.handle, r.priority, NULL);
- DCHECK(rv == OK);
- r.callback->Run(rv);
- return;
+ if (may_have_stalled_group_) {
+ // The highest priority pending request may belong to another group, so
+ // check all of them. Worst-case this takes |max_sockets_| iterations.
+ if (Group* top_group = FindTopStalledGroup())
+ StartPendingRequestForGroup(top_group);
+
+ // Check if there are any stalled groups left.
+ if (!FindTopStalledGroup())
+ may_have_stalled_group_ = false;
+
+ } else if (!group.pending_requests.empty()) {
+ // Otherwise just dequeue the first pending request of |group|.
+ StartPendingRequestForGroup(&group);
}
// Delete group if no longer needed.
- if (group.active_socket_count == 0 && group.idle_sockets.empty()) {
- DCHECK(group.pending_requests.empty());
+ if (group.empty())
group_map_.erase(i);
+}
+
+void ClientSocketPool::StartPendingRequestForGroup(Group* group) {
+ Request r = group->pending_requests.front();
+ group->pending_requests.pop_front();
+ int rv = RequestSocket(r.handle, r.priority, NULL);
+ DCHECK(rv == OK);
+ r.callback->Run(rv);
+}
+
+// Search for the highest priority pending request, amongst the groups that
+// are not at the |max_sockets_per_group_| limit. Note: for requests with
+// the same priority, the winner is based on group hash ordering (and not
+// insertion order).
+ClientSocketPool::Group* ClientSocketPool::FindTopStalledGroup() {
+ Group* top_group = NULL;
+ for (GroupMap::iterator i = group_map_.begin(); i != group_map_.end(); ++i) {
+ Group* group = &i->second;
+ const RequestQueue& queue = group->pending_requests;
+ if (group->active_socket_count < max_sockets_per_group_ &&
+ !queue.empty() && (top_group == NULL || queue.front().priority >
+ top_group->pending_requests.front().priority)) {
+ top_group = group;
+ }
}
+ return top_group;
}
} // namespace net
« no previous file with comments | « net/base/client_socket_pool.h ('k') | net/http/http_network_session.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698