ClientSocketPoolBaseHelper can try to read an invalid iterator. Fix that.
If we hit the backup socket timer and there is no pending request, then the
code still tries to create a backup socket using pending_requests.begin().
We change the code to cancel the backup socket timer when the pending_requests
hit zero. We also check before reading pending_requests.begin().
BUG=53860
TEST=ClientsocketPoolBaseTest.CancelBackupSocketWhenThereAreNoRequests
Review URL: http://codereview.chromium.org/3247007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57993 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index ff67e3b..71074a9 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -1940,8 +1940,8 @@
CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
pool_->EnableConnectBackupJobs();
- // Create the first socket and set to ERR_IO_PENDING. This creates a
- // backup job.
+ // Create the first socket and set to ERR_IO_PENDING. This starts the backup
+ // timer.
connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -1969,6 +1969,30 @@
EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
}
+TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketWhenThereAreNoRequests) {
+ CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
+ pool_->EnableConnectBackupJobs();
+
+ // Create the first socket and set to ERR_IO_PENDING. This starts the backup
+ // timer.
+ connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
+ ClientSocketHandle handle;
+ TestCompletionCallback callback;
+ EXPECT_EQ(ERR_IO_PENDING, handle.Init("bar", params_, kDefaultPriority,
+ &callback, pool_, BoundNetLog()));
+ ASSERT_TRUE(pool_->HasGroup("bar"));
+ EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
+
+ // Cancel the socket request. This should cancel the backup timer. Wait for
+ // the backup time to see if it indeed got canceled.
+ handle.Reset();
+ // Wait for the backup timer to fire (add some slop to ensure it fires)
+ PlatformThread::Sleep(ClientSocketPool::kMaxConnectRetryIntervalMs / 2 * 3);
+ MessageLoop::current()->RunAllPending();
+ ASSERT_TRUE(pool_->HasGroup("bar"));
+ EXPECT_EQ(1, pool_->NumConnectJobsInGroup("bar"));
+}
+
// Test delayed socket binding for the case where we have two connects,
// and while one is waiting on a connect, the other frees up.
// The socket waiting on a connect should switch immediately to the freed