summaryrefslogtreecommitdiffstats
path: root/net/socket
diff options
context:
space:
mode:
authormarkus@chromium.org <markus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 23:53:51 +0000
committermarkus@chromium.org <markus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 23:53:51 +0000
commit545a8b0702d8054b669438e9ad3900c1b11a5123 (patch)
tree3b8c4847c2d2143cc430436ceebcb1877474ff17 /net/socket
parentecb0a024ee469a8d591fb95ac4f8db9c6217f462 (diff)
downloadchromium_src-545a8b0702d8054b669438e9ad3900c1b11a5123.zip
chromium_src-545a8b0702d8054b669438e9ad3900c1b11a5123.tar.gz
chromium_src-545a8b0702d8054b669438e9ad3900c1b11a5123.tar.bz2
When converting between units of time or data types of different precision,
we have to be careful to consistently round in the same direction. Timeout checks usually check if Now() is less or equal to a deadline in order to determine if a timeout has occurred. This correctly handles the case where actual sleep times are equal or longer than requested sleep times. But if we round down when setting the sleep delay, this can result in unnecessary and expensive looping. Make sure, we always round up when converting to a format with less precision. BUG=none TEST=none Review URL: http://codereview.chromium.org/196053 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27146 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/socket')
-rw-r--r--net/socket/client_socket_pool_base_unittest.cc39
-rw-r--r--net/socket/socket_test_util.cc9
2 files changed, 37 insertions, 11 deletions
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index 249d7e3..c0a04aa 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -143,31 +143,34 @@ class TestConnectJob : public ConnectJob {
return DoConnect(false /* error */, false /* sync */);
case kMockPendingJob:
set_load_state(LOAD_STATE_CONNECTING);
- MessageLoop::current()->PostTask(
+ MessageLoop::current()->PostDelayedTask(
FROM_HERE,
method_factory_.NewRunnableMethod(
- &TestConnectJob::DoConnect,
- true /* successful */,
- true /* async */));
+ &TestConnectJob::DoConnect,
+ true /* successful */,
+ true /* async */),
+ 2);
return ERR_IO_PENDING;
case kMockPendingFailingJob:
set_load_state(LOAD_STATE_CONNECTING);
- MessageLoop::current()->PostTask(
+ MessageLoop::current()->PostDelayedTask(
FROM_HERE,
method_factory_.NewRunnableMethod(
- &TestConnectJob::DoConnect,
- false /* error */,
- true /* async */));
+ &TestConnectJob::DoConnect,
+ false /* error */,
+ true /* async */),
+ 2);
return ERR_IO_PENDING;
case kMockWaitingJob:
client_socket_factory_->WaitForSignal(this);
waiting_success_ = true;
return ERR_IO_PENDING;
case kMockAdvancingLoadStateJob:
- MessageLoop::current()->PostTask(
+ MessageLoop::current()->PostDelayedTask(
FROM_HERE,
method_factory_.NewRunnableMethod(
- &TestConnectJob::AdvanceLoadState, load_state_));
+ &TestConnectJob::AdvanceLoadState, load_state_),
+ 2);
return ERR_IO_PENDING;
default:
NOTREACHED();
@@ -717,6 +720,8 @@ TEST_F(ClientSocketPoolBaseTest, TotalLimitCountsConnectingSockets) {
// Create one asynchronous request.
connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob);
EXPECT_EQ(ERR_IO_PENDING, StartRequest("d", kDefaultPriority));
+ PlatformThread::Sleep(10);
+ MessageLoop::current()->RunAllPending();
// The next synchronous request should wait for its turn.
connect_job_factory_->set_job_type(TestConnectJob::kMockJob);
@@ -953,14 +958,26 @@ class RequestSocketCallback : public CallbackRunner< Tuple1<int> > {
test_connect_job_factory_->set_job_type(next_job_type_);
handle_->Reset();
within_callback_ = true;
+ TestCompletionCallback next_job_callback;
int rv = InitHandle(
- handle_, "a", kDefaultPriority, this, pool_.get(), NULL);
+ handle_, "a", kDefaultPriority, &next_job_callback, pool_.get(),
+ NULL);
switch (next_job_type_) {
case TestConnectJob::kMockJob:
EXPECT_EQ(OK, rv);
break;
case TestConnectJob::kMockPendingJob:
EXPECT_EQ(ERR_IO_PENDING, rv);
+
+ // For pending jobs, wait for new socket to be created. This makes
+ // sure there are no more pending operations nor any unclosed sockets
+ // when the test finishes.
+ // We need to give it a little bit of time to run, so that all the
+ // operations that happen on timers (e.g. cleanup of idle
+ // connections) can execute.
+ MessageLoop::current()->SetNestableTasksAllowed(true);
+ PlatformThread::Sleep(10);
+ EXPECT_EQ(OK, next_job_callback.WaitForResult());
break;
default:
FAIL() << "Unexpected job type: " << next_job_type_;
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index cd4423b..7f4af08 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -343,6 +343,15 @@ void ClientSocketPoolTest::SetUp() {
void ClientSocketPoolTest::TearDown() {
// The tests often call Reset() on handles at the end which may post
// DoReleaseSocket() tasks.
+ // Pending tasks created by client_socket_pool_base_unittest.cc are
+ // posted two milliseconds into the future and thus won't become
+ // scheduled until that time.
+ // We wait a few milliseconds to make sure that all such future tasks
+ // are ready to run, before calling RunAllPending(). This will work
+ // correctly even if Sleep() finishes late (and it should never finish
+ // early), as all we have to ensure is that actual wall-time has progressed
+ // past the scheduled starting time of the pending task.
+ PlatformThread::Sleep(10);
MessageLoop::current()->RunAllPending();
}