diff options
author | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-03 18:10:16 +0000 |
---|---|---|
committer | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-03 18:10:16 +0000 |
commit | 4f2abecdad4ff2ac012926f33058cf2dbf2e4c88 (patch) | |
tree | 235a82a01f959451a40af00df0e8f909193d95b5 /net | |
parent | 7635957f7207b6b4824a2c3ab8c0cfa9f5b64f65 (diff) | |
download | chromium_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.cc | 31 | ||||
-rw-r--r-- | net/socket/client_socket_pool_base_unittest.cc | 41 |
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 |