Fix a bug in backup socket cleanup where when we call RemoveConnectJob,
we didn't necessarily cleanup the pending backup socket task.
In addition to this, make the OnBackupSocketTimerFired more robust -
in the case that this ever should happen, it will simply fallout
rather than triggering a CRASH (and burn).
Test case included.
BUG=47375
TEST=ClientSocketPoolBaseTest.BackupSocketCancelAtMaxSockets
Review URL: http://codereview.chromium.org/2942006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52049 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 7b84d94..1dcf897 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -1784,6 +1784,45 @@
EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type());
}
+// Cancel a pending socket request while we're at max sockets,
+// and verify that the backup socket firing doesn't cause a crash.
+TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) {
+ // Max 4 sockets globally, max 4 sockets per group.
+ CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
+ pool_->EnableBackupJobs();
+
+ // Create the first socket and set to ERR_IO_PENDING. This creates a
+ // backup job.
+ connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob);
+ ClientSocketHandle handle;
+ TestCompletionCallback callback;
+ EXPECT_EQ(
+ ERR_IO_PENDING,
+ InitHandle(
+ &handle, "bar", kDefaultPriority, &callback, pool_, BoundNetLog()));
+
+ // Start (MaxSockets - 1) connected sockets to reach max sockets.
+ connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
+ ClientSocketHandle handles[kDefaultMaxSockets];
+ for (int i = 1; i < kDefaultMaxSockets; ++i) {
+ TestCompletionCallback callback;
+ EXPECT_EQ(OK,
+ InitHandle(&handles[i], "bar", kDefaultPriority,
+ &callback, pool_, BoundNetLog()));
+ }
+
+ MessageLoop::current()->RunAllPending();
+
+ // Cancel the pending request.
+ 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();
+ EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count());
+}
+
} // namespace
} // namespace net