OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/socket/client_socket_pool_base.h" | 5 #include "net/socket/client_socket_pool_base.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/platform_thread.h" | 9 #include "base/platform_thread.h" |
10 #include "base/scoped_vector.h" | 10 #include "base/scoped_vector.h" |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 AddressList ignored; | 136 AddressList ignored; |
137 client_socket_factory_->CreateTCPClientSocket(ignored); | 137 client_socket_factory_->CreateTCPClientSocket(ignored); |
138 set_socket(new MockClientSocket()); | 138 set_socket(new MockClientSocket()); |
139 switch (job_type_) { | 139 switch (job_type_) { |
140 case kMockJob: | 140 case kMockJob: |
141 return DoConnect(true /* successful */, false /* sync */); | 141 return DoConnect(true /* successful */, false /* sync */); |
142 case kMockFailingJob: | 142 case kMockFailingJob: |
143 return DoConnect(false /* error */, false /* sync */); | 143 return DoConnect(false /* error */, false /* sync */); |
144 case kMockPendingJob: | 144 case kMockPendingJob: |
145 set_load_state(LOAD_STATE_CONNECTING); | 145 set_load_state(LOAD_STATE_CONNECTING); |
146 MessageLoop::current()->PostTask( | 146 |
| 147 // Depending on execution timings, posting a delayed task can result |
| 148 // in the task getting executed the at the earliest possible |
| 149 // opportunity or only after returning once from the message loop and |
| 150 // then a second call into the message loop. In order to make behavior |
| 151 // more deterministic, we change the default delay to 2ms. This should |
| 152 // always require us to wait for the second call into the message loop. |
| 153 // |
| 154 // N.B. The correct fix for this and similar timing problems is to |
| 155 // abstract time for the purpose of unittests. Unfortunately, we have |
| 156 // a lot of third-party components that directly call the various |
| 157 // time functions, so this change would be rather invasive. |
| 158 MessageLoop::current()->PostDelayedTask( |
147 FROM_HERE, | 159 FROM_HERE, |
148 method_factory_.NewRunnableMethod( | 160 method_factory_.NewRunnableMethod( |
149 &TestConnectJob::DoConnect, | 161 &TestConnectJob::DoConnect, |
150 true /* successful */, | 162 true /* successful */, |
151 true /* async */)); | 163 true /* async */), |
| 164 2); |
152 return ERR_IO_PENDING; | 165 return ERR_IO_PENDING; |
153 case kMockPendingFailingJob: | 166 case kMockPendingFailingJob: |
154 set_load_state(LOAD_STATE_CONNECTING); | 167 set_load_state(LOAD_STATE_CONNECTING); |
155 MessageLoop::current()->PostTask( | 168 MessageLoop::current()->PostDelayedTask( |
156 FROM_HERE, | 169 FROM_HERE, |
157 method_factory_.NewRunnableMethod( | 170 method_factory_.NewRunnableMethod( |
158 &TestConnectJob::DoConnect, | 171 &TestConnectJob::DoConnect, |
159 false /* error */, | 172 false /* error */, |
160 true /* async */)); | 173 true /* async */), |
| 174 2); |
161 return ERR_IO_PENDING; | 175 return ERR_IO_PENDING; |
162 case kMockWaitingJob: | 176 case kMockWaitingJob: |
163 client_socket_factory_->WaitForSignal(this); | 177 client_socket_factory_->WaitForSignal(this); |
164 waiting_success_ = true; | 178 waiting_success_ = true; |
165 return ERR_IO_PENDING; | 179 return ERR_IO_PENDING; |
166 case kMockAdvancingLoadStateJob: | 180 case kMockAdvancingLoadStateJob: |
167 MessageLoop::current()->PostTask( | 181 MessageLoop::current()->PostDelayedTask( |
168 FROM_HERE, | 182 FROM_HERE, |
169 method_factory_.NewRunnableMethod( | 183 method_factory_.NewRunnableMethod( |
170 &TestConnectJob::AdvanceLoadState, load_state_)); | 184 &TestConnectJob::AdvanceLoadState, load_state_), |
| 185 2); |
171 return ERR_IO_PENDING; | 186 return ERR_IO_PENDING; |
172 default: | 187 default: |
173 NOTREACHED(); | 188 NOTREACHED(); |
174 set_socket(NULL); | 189 set_socket(NULL); |
175 return ERR_FAILED; | 190 return ERR_FAILED; |
176 } | 191 } |
177 } | 192 } |
178 | 193 |
179 void set_load_state(LoadState load_state) { load_state_ = load_state; } | 194 void set_load_state(LoadState load_state) { load_state_ = load_state; } |
180 | 195 |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 used_idle_socket_timeout, | 404 used_idle_socket_timeout, |
390 connect_job_factory_); | 405 connect_job_factory_); |
391 } | 406 } |
392 | 407 |
393 int StartRequest(const std::string& group_name, int priority) { | 408 int StartRequest(const std::string& group_name, int priority) { |
394 return StartRequestUsingPool<TestClientSocketPool, const void*>( | 409 return StartRequestUsingPool<TestClientSocketPool, const void*>( |
395 pool_.get(), group_name, priority, NULL); | 410 pool_.get(), group_name, priority, NULL); |
396 } | 411 } |
397 | 412 |
398 virtual void TearDown() { | 413 virtual void TearDown() { |
| 414 // We post all of our delayed tasks with a 2ms delay. I.e. they don't |
| 415 // actually become pending until 2ms after they have been created. In order |
| 416 // to flush all tasks, we need to wait so that we know there are no |
| 417 // soon-to-be-pending tasks waiting. |
| 418 PlatformThread::Sleep(10); |
| 419 MessageLoop::current()->RunAllPending(); |
| 420 |
399 // Need to delete |pool_| before we turn late binding back off. We also need | 421 // Need to delete |pool_| before we turn late binding back off. We also need |
400 // to delete |requests_| because the pool is reference counted and requests | 422 // to delete |requests_| because the pool is reference counted and requests |
401 // keep reference to it. | 423 // keep reference to it. |
402 // TODO(willchan): Remove this part when late binding becomes the default. | 424 // TODO(willchan): Remove this part when late binding becomes the default. |
403 pool_ = NULL; | 425 pool_ = NULL; |
404 requests_.reset(); | 426 requests_.reset(); |
405 | 427 |
406 EnableLateBindingOfSockets(false); | 428 EnableLateBindingOfSockets(false); |
407 | 429 |
408 ClientSocketPoolTest::TearDown(); | 430 ClientSocketPoolTest::TearDown(); |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); | 730 CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); |
709 | 731 |
710 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority)); | 732 EXPECT_EQ(OK, StartRequest("a", kDefaultPriority)); |
711 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority)); | 733 EXPECT_EQ(OK, StartRequest("b", kDefaultPriority)); |
712 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority)); | 734 EXPECT_EQ(OK, StartRequest("c", kDefaultPriority)); |
713 | 735 |
714 // Create one asynchronous request. | 736 // Create one asynchronous request. |
715 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); | 737 connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); |
716 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority)); | 738 EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority)); |
717 | 739 |
| 740 // We post all of our delayed tasks with a 2ms delay. I.e. they don't |
| 741 // actually become pending until 2ms after they have been created. In order |
| 742 // to flush all tasks, we need to wait so that we know there are no |
| 743 // soon-to-be-pending tasks waiting. |
| 744 PlatformThread::Sleep(10); |
| 745 MessageLoop::current()->RunAllPending(); |
| 746 |
718 // The next synchronous request should wait for its turn. | 747 // The next synchronous request should wait for its turn. |
719 connect_job_factory_->set_job_type(TestConnectJob::kMockJob); | 748 connect_job_factory_->set_job_type(TestConnectJob::kMockJob); |
720 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority)); | 749 EXPECT_EQ(ERR_IO_PENDING, StartRequest("e", kDefaultPriority)); |
721 | 750 |
722 ReleaseAllConnections(KEEP_ALIVE); | 751 ReleaseAllConnections(KEEP_ALIVE); |
723 | 752 |
724 EXPECT_EQ(static_cast<int>(requests_.size()), | 753 EXPECT_EQ(static_cast<int>(requests_.size()), |
725 client_socket_factory_.allocation_count()); | 754 client_socket_factory_.allocation_count()); |
726 | 755 |
727 EXPECT_EQ(1, GetOrderOfRequest(1)); | 756 EXPECT_EQ(1, GetOrderOfRequest(1)); |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
943 next_job_type_(next_job_type) {} | 972 next_job_type_(next_job_type) {} |
944 | 973 |
945 virtual void RunWithParams(const Tuple1<int>& params) { | 974 virtual void RunWithParams(const Tuple1<int>& params) { |
946 callback_.RunWithParams(params); | 975 callback_.RunWithParams(params); |
947 ASSERT_EQ(OK, params.a); | 976 ASSERT_EQ(OK, params.a); |
948 | 977 |
949 if (!within_callback_) { | 978 if (!within_callback_) { |
950 test_connect_job_factory_->set_job_type(next_job_type_); | 979 test_connect_job_factory_->set_job_type(next_job_type_); |
951 handle_->Reset(); | 980 handle_->Reset(); |
952 within_callback_ = true; | 981 within_callback_ = true; |
| 982 TestCompletionCallback next_job_callback; |
953 int rv = InitHandle( | 983 int rv = InitHandle( |
954 handle_, "a", kDefaultPriority, this, pool_.get(), NULL); | 984 handle_, "a", kDefaultPriority, &next_job_callback, pool_.get(), |
| 985 NULL); |
955 switch (next_job_type_) { | 986 switch (next_job_type_) { |
956 case TestConnectJob::kMockJob: | 987 case TestConnectJob::kMockJob: |
957 EXPECT_EQ(OK, rv); | 988 EXPECT_EQ(OK, rv); |
958 break; | 989 break; |
959 case TestConnectJob::kMockPendingJob: | 990 case TestConnectJob::kMockPendingJob: |
960 EXPECT_EQ(ERR_IO_PENDING, rv); | 991 EXPECT_EQ(ERR_IO_PENDING, rv); |
| 992 |
| 993 // For pending jobs, wait for new socket to be created. This makes |
| 994 // sure there are no more pending operations nor any unclosed sockets |
| 995 // when the test finishes. |
| 996 // We need to give it a little bit of time to run, so that all the |
| 997 // operations that happen on timers (e.g. cleanup of idle |
| 998 // connections) can execute. |
| 999 MessageLoop::current()->SetNestableTasksAllowed(true); |
| 1000 PlatformThread::Sleep(10); |
| 1001 EXPECT_EQ(OK, next_job_callback.WaitForResult()); |
961 break; | 1002 break; |
962 default: | 1003 default: |
963 FAIL() << "Unexpected job type: " << next_job_type_; | 1004 FAIL() << "Unexpected job type: " << next_job_type_; |
964 break; | 1005 break; |
965 } | 1006 } |
966 } | 1007 } |
967 } | 1008 } |
968 | 1009 |
969 int WaitForResult() { | 1010 int WaitForResult() { |
970 return callback_.WaitForResult(); | 1011 return callback_.WaitForResult(); |
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1805 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle())); | 1846 EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState("a", req2.handle())); |
1806 | 1847 |
1807 // Cancel one of the requests. Wait for the other, which will get the first | 1848 // Cancel one of the requests. Wait for the other, which will get the first |
1808 // job. Release the socket. Run the loop again to make sure the second | 1849 // job. Release the socket. Run the loop again to make sure the second |
1809 // socket is sitting idle and the first one is released (since ReleaseSocket() | 1850 // socket is sitting idle and the first one is released (since ReleaseSocket() |
1810 // just posts a DoReleaseSocket() task). | 1851 // just posts a DoReleaseSocket() task). |
1811 | 1852 |
1812 req.handle()->Reset(); | 1853 req.handle()->Reset(); |
1813 EXPECT_EQ(OK, req2.WaitForResult()); | 1854 EXPECT_EQ(OK, req2.WaitForResult()); |
1814 req2.handle()->Reset(); | 1855 req2.handle()->Reset(); |
| 1856 |
| 1857 // We post all of our delayed tasks with a 2ms delay. I.e. they don't |
| 1858 // actually become pending until 2ms after they have been created. In order |
| 1859 // to flush all tasks, we need to wait so that we know there are no |
| 1860 // soon-to-be-pending tasks waiting. |
| 1861 PlatformThread::Sleep(10); |
1815 MessageLoop::current()->RunAllPending(); | 1862 MessageLoop::current()->RunAllPending(); |
1816 | 1863 |
1817 ASSERT_EQ(2, pool_->IdleSocketCount()); | 1864 ASSERT_EQ(2, pool_->IdleSocketCount()); |
1818 | 1865 |
1819 // Invoke the idle socket cleanup check. Only one socket should be left, the | 1866 // Invoke the idle socket cleanup check. Only one socket should be left, the |
1820 // used socket. Request it to make sure that it's used. | 1867 // used socket. Request it to make sure that it's used. |
1821 | 1868 |
1822 pool_->CleanupTimedOutIdleSockets(); | 1869 pool_->CleanupTimedOutIdleSockets(); |
1823 rv = InitHandle(req.handle(), "a", 0, &req, pool_.get(), NULL); | 1870 rv = InitHandle(req.handle(), "a", 0, &req, pool_.get(), NULL); |
1824 EXPECT_EQ(OK, rv); | 1871 EXPECT_EQ(OK, rv); |
1825 EXPECT_TRUE(req.handle()->is_reused()); | 1872 EXPECT_TRUE(req.handle()->is_reused()); |
1826 } | 1873 } |
1827 | 1874 |
1828 } // namespace | 1875 } // namespace |
1829 | 1876 |
1830 } // namespace net | 1877 } // namespace net |
OLD | NEW |