| Index: net/socket/client_socket_pool_base_unittest.cc
|
| diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
|
| index 3e20eb9b87286815f7ba504b738aa14fb7c6203c..7e26ec6670f923246044820adb9baffa9e7246f9 100644
|
| --- a/net/socket/client_socket_pool_base_unittest.cc
|
| +++ b/net/socket/client_socket_pool_base_unittest.cc
|
| @@ -1455,6 +1455,70 @@ TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) {
|
| EXPECT_FALSE(req4.handle()->is_reused());
|
| }
|
|
|
| +// Regression test for http://crbug.com/42267.
|
| +// When DoReleaseSocket() is processed for one socket, it is blocked because the
|
| +// other stalled groups all have releasing sockets, so no progress can be made.
|
| +TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) {
|
| + CreatePoolWithIdleTimeouts(
|
| + 4 /* socket limit */, 4 /* socket limit per group */,
|
| + 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);
|
| +
|
| + // Max out the socket limit with 2 per group.
|
| +
|
| + scoped_ptr<TestSocketRequest> req_a[4];
|
| + scoped_ptr<TestSocketRequest> req_b[4];
|
| +
|
| + for (int i = 0; i < 2; ++i) {
|
| + req_a[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
|
| + req_b[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
|
| + EXPECT_EQ(OK,
|
| + InitHandle(req_a[i]->handle(), "a", LOWEST, req_a[i].get(), pool_,
|
| + BoundNetLog()));
|
| + EXPECT_EQ(OK,
|
| + InitHandle(req_b[i]->handle(), "b", LOWEST, req_b[i].get(), pool_,
|
| + BoundNetLog()));
|
| + }
|
| +
|
| + // Make 4 pending requests, 2 per group.
|
| +
|
| + for (int i = 2; i < 4; ++i) {
|
| + req_a[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
|
| + req_b[i].reset(new TestSocketRequest(&request_order_, &completion_count_));
|
| + EXPECT_EQ(ERR_IO_PENDING,
|
| + InitHandle(req_a[i]->handle(), "a", LOWEST, req_a[i].get(), pool_,
|
| + BoundNetLog()));
|
| + EXPECT_EQ(ERR_IO_PENDING,
|
| + InitHandle(req_b[i]->handle(), "b", LOWEST, req_b[i].get(), pool_,
|
| + BoundNetLog()));
|
| + }
|
| +
|
| + // Release b's socket first. The order is important, because in
|
| + // DoReleaseSocket(), we'll process b's released socket, and since both b and
|
| + // a are stalled, but 'a' is lower lexicographically, we'll process group 'a'
|
| + // first, which has a releasing socket, so it refuses to start up another
|
| + // ConnectJob. So, we used to infinite loop on this.
|
| + req_b[0]->handle()->socket()->Disconnect();
|
| + req_b[0]->handle()->Reset();
|
| + req_a[0]->handle()->socket()->Disconnect();
|
| + req_a[0]->handle()->Reset();
|
| +
|
| + // Used to get stuck here.
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| + req_b[1]->handle()->socket()->Disconnect();
|
| + req_b[1]->handle()->Reset();
|
| + req_a[1]->handle()->socket()->Disconnect();
|
| + req_a[1]->handle()->Reset();
|
| +
|
| + for (int i = 2; i < 4; ++i) {
|
| + EXPECT_EQ(OK, req_b[i]->WaitForResult());
|
| + EXPECT_EQ(OK, req_a[i]->WaitForResult());
|
| + }
|
| +}
|
| +
|
| TEST_F(ClientSocketPoolBaseTest,
|
| ReleasingDisconnectedSocketsMaintainsPriorityOrder) {
|
| CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
|
|
|