Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(409)

Unified Diff: net/socket/client_socket_pool_base_unittest.cc

Issue 2050005: Reland 46757. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Reduce large iteration check. Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/socket/client_socket_pool_base.cc ('k') | net/socket/tcp_client_socket_pool_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..f21ee55b59af50d814285a87edaca4b149f63f13 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -830,6 +830,31 @@ TEST_F(ClientSocketPoolBaseTest, CorrectlyCountStalledGroups) {
EXPECT_EQ(kDefaultMaxSockets + 2, client_socket_factory_.allocation_count());
}
+TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) {
+ CreatePool(kDefaultMaxSockets, kDefaultMaxSockets);
+ connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
+
+ ClientSocketHandle handle;
+ TestCompletionCallback callback;
+ EXPECT_EQ(ERR_IO_PENDING,
+ InitHandle(&handle, "a", kDefaultPriority, &callback, pool_,
+ BoundNetLog()));
+
+ ClientSocketHandle handles[4];
+ for (size_t i = 0; i < arraysize(handles); ++i) {
+ TestCompletionCallback callback;
+ EXPECT_EQ(ERR_IO_PENDING,
+ InitHandle(&handles[i], "b", kDefaultPriority, &callback, pool_,
+ BoundNetLog()));
+ }
+
+ // One will be stalled, cancel all the handles now.
+ // This should hit the OnAvailableSocketSlot() code where we previously had
+ // stalled groups, but no longer have any.
+ for (size_t i = 0; i < arraysize(handles); ++i)
+ handles[i].Reset();
+}
+
TEST_F(ClientSocketPoolBaseTest, PendingRequests) {
CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup);
@@ -1455,6 +1480,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);
« no previous file with comments | « net/socket/client_socket_pool_base.cc ('k') | net/socket/tcp_client_socket_pool_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698