summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-03 18:10:16 +0000
committerwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-03 18:10:16 +0000
commit4f2abecdad4ff2ac012926f33058cf2dbf2e4c88 (patch)
tree235a82a01f959451a40af00df0e8f909193d95b5 /net
parent7635957f7207b6b4824a2c3ab8c0cfa9f5b64f65 (diff)
downloadchromium_src-4f2abecdad4ff2ac012926f33058cf2dbf2e4c88.zip
chromium_src-4f2abecdad4ff2ac012926f33058cf2dbf2e4c88.tar.gz
chromium_src-4f2abecdad4ff2ac012926f33058cf2dbf2e4c88.tar.bz2
Socket late binding bugfix.
I added code in r36144 so that we wouldn't create extra ConnectJobs if we were still releasing sockets. This code did not handle the case where we had multiple disconnected releasing sockets. I've added a test and code to cover this case now. BUG=34123 Review URL: http://codereview.chromium.org/557089 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37984 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/socket/client_socket_pool_base.cc31
-rw-r--r--net/socket/client_socket_pool_base_unittest.cc41
2 files changed, 72 insertions, 0 deletions
diff --git a/net/socket/client_socket_pool_base.cc b/net/socket/client_socket_pool_base.cc
index 9b14f4b..24c2dc6 100644
--- a/net/socket/client_socket_pool_base.cc
+++ b/net/socket/client_socket_pool_base.cc
@@ -395,7 +395,38 @@ void ClientSocketPoolBaseHelper::DoReleaseSocket(const std::string& group_name,
delete socket;
}
+ const bool more_releasing_sockets = group.num_releasing_sockets > 0;
+
OnAvailableSocketSlot(group_name, &group);
+
+ // If there are no more releasing sockets, then we might have to process
+ // multiple available socket slots, since we stalled their processing until
+ // all sockets have been released.
+ if (more_releasing_sockets)
+ return;
+
+ while (true) {
+ // We can't activate more sockets since we're already at our global limit.
+ if (ReachedMaxSocketsLimit())
+ return;
+
+ // |group| might now be deleted.
+ i = group_map_.find(group_name);
+ if (i == group_map_.end())
+ return;
+
+ group = i->second;
+
+ // If we already have enough ConnectJobs to satisfy the pending requests,
+ // don't bother starting up more.
+ if (group.pending_requests.size() <= group.jobs.size())
+ return;
+
+ if (!group.HasAvailableSocketSlot(max_sockets_per_group_))
+ return;
+
+ OnAvailableSocketSlot(group_name, &group);
+ }
}
// Search for the highest priority pending request, amongst the groups that
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index d4c510f8..9f875ad 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -1389,6 +1389,47 @@ TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSockets) {
EXPECT_TRUE(req.handle()->is_reused());
}
+// Make sure that we process all pending requests even when we're stalling
+// because of multiple releasing disconnected sockets.
+TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
+ CreatePoolWithIdleTimeouts(
+ kDefaultMaxSockets, kDefaultMaxSocketsPerGroup,
+ base::TimeDelta(), // Time out unused sockets immediately.
+ base::TimeDelta::FromDays(1)); // Don't time out used sockets.
+
+ connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
+
+ // Startup 4 connect jobs. Two of them will be pending.
+
+ TestSocketRequest req(&request_order_, &completion_count_);
+ int rv = InitHandle(req.handle(), "a", LOWEST, &req, pool_.get(), NULL);
+ EXPECT_EQ(OK, rv);
+
+ TestSocketRequest req2(&request_order_, &completion_count_);
+ rv = InitHandle(req2.handle(), "a", LOWEST, &req2, pool_.get(), NULL);
+ EXPECT_EQ(OK, rv);
+
+ TestSocketRequest req3(&request_order_, &completion_count_);
+ rv = InitHandle(req3.handle(), "a", LOWEST, &req3, pool_.get(), NULL);
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ TestSocketRequest req4(&request_order_, &completion_count_);
+ rv = InitHandle(req4.handle(), "a", LOWEST, &req4, pool_.get(), NULL);
+ EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ // Release two disconnected sockets.
+
+ req.handle()->socket()->Disconnect();
+ req.handle()->Reset();
+ req2.handle()->socket()->Disconnect();
+ req2.handle()->Reset();
+
+ EXPECT_EQ(OK, req3.WaitForResult());
+ EXPECT_FALSE(req3.handle()->is_reused());
+ EXPECT_EQ(OK, req4.WaitForResult());
+ EXPECT_FALSE(req4.handle()->is_reused());
+}
+
} // namespace
} // namespace net