| Index: base/threading/sequenced_worker_pool_unittest.cc
|
| diff --git a/base/threading/sequenced_worker_pool_unittest.cc b/base/threading/sequenced_worker_pool_unittest.cc
|
| index 18270a6f4f913bea794be5c70d4c710f8b291212..23e707f2bb200c7f10ce7fedca3d5e8ba9650c9b 100644
|
| --- a/base/threading/sequenced_worker_pool_unittest.cc
|
| +++ b/base/threading/sequenced_worker_pool_unittest.cc
|
| @@ -8,6 +8,7 @@
|
|
|
| #include <algorithm>
|
| #include <memory>
|
| +#include <utility>
|
|
|
| #include "base/bind.h"
|
| #include "base/compiler_specific.h"
|
| @@ -17,6 +18,9 @@
|
| #include "base/stl_util.h"
|
| #include "base/synchronization/condition_variable.h"
|
| #include "base/synchronization/lock.h"
|
| +#include "base/task_scheduler/scheduler_worker_pool_params.h"
|
| +#include "base/task_scheduler/task_scheduler.h"
|
| +#include "base/task_scheduler/task_scheduler_impl.h"
|
| #include "base/test/sequenced_task_runner_test_template.h"
|
| #include "base/test/sequenced_worker_pool_owner.h"
|
| #include "base/test/task_runner_test_template.h"
|
| @@ -36,7 +40,8 @@ namespace base {
|
|
|
| namespace {
|
|
|
| -const size_t kNumWorkerThreads = 3;
|
| +constexpr size_t kNumWorkerThreads = 3;
|
| +constexpr size_t kNumAllowedBlockShutdownTasks = 1000;
|
|
|
| // Allows a number of threads to all be blocked on the same event, and
|
| // provides a way to unblock a certain number of them.
|
| @@ -231,13 +236,46 @@ class TestTracker : public base::RefCountedThreadSafe<TestTracker> {
|
| size_t started_events_;
|
| };
|
|
|
| -class SequencedWorkerPoolTest : public testing::Test {
|
| +enum class SequencedWorkerPoolRedirection { NONE, TO_TASK_SCHEDULER };
|
| +
|
| +void StartRedirectionToTaskScheduler(size_t num_threads) {
|
| + std::vector<SchedulerWorkerPoolParams> worker_pool_params;
|
| + worker_pool_params.emplace_back(
|
| + "SchedulerWorkerPoolName", ThreadPriority::NORMAL,
|
| + SchedulerWorkerPoolParams::IORestriction::ALLOWED, num_threads,
|
| + TimeDelta::Max());
|
| + TaskScheduler::CreateAndSetDefaultTaskScheduler(
|
| + std::move(worker_pool_params),
|
| + base::Bind([](const TaskTraits&) -> size_t { return 0U; }));
|
| + SequencedWorkerPool::ResetRedirectToTaskSchedulerForProcessForTesting();
|
| + SequencedWorkerPool::RedirectToTaskSchedulerForProcess();
|
| +}
|
| +
|
| +void StopRedirectionToTaskScheduler() {
|
| + SequencedWorkerPool::ResetRedirectToTaskSchedulerForProcessForTesting();
|
| + static_cast<internal::TaskSchedulerImpl*>(TaskScheduler::GetInstance())
|
| + ->JoinForTesting();
|
| + TaskScheduler::SetInstance(nullptr);
|
| +}
|
| +
|
| +class SequencedWorkerPoolTest
|
| + : public testing::TestWithParam<SequencedWorkerPoolRedirection> {
|
| public:
|
| SequencedWorkerPoolTest()
|
| : tracker_(new TestTracker) {
|
| ResetPool();
|
| }
|
|
|
| + void SetUp() override {
|
| + if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
|
| + StartRedirectionToTaskScheduler(kNumWorkerThreads);
|
| + }
|
| +
|
| + void TearDown() override {
|
| + if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
|
| + StopRedirectionToTaskScheduler();
|
| + }
|
| +
|
| const scoped_refptr<SequencedWorkerPool>& pool() {
|
| return pool_owner_->pool();
|
| }
|
| @@ -332,7 +370,7 @@ void HoldPoolReference(const scoped_refptr<base::SequencedWorkerPool>& pool,
|
| }
|
|
|
| // Tests that delayed tasks are deleted upon shutdown of the pool.
|
| -TEST_F(SequencedWorkerPoolTest, DelayedTaskDuringShutdown) {
|
| +TEST_P(SequencedWorkerPoolTest, DelayedTaskDuringShutdown) {
|
| // Post something to verify the pool is started up.
|
| EXPECT_TRUE(pool()->PostTask(
|
| FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 1)));
|
| @@ -353,20 +391,26 @@ TEST_F(SequencedWorkerPoolTest, DelayedTaskDuringShutdown) {
|
| ASSERT_EQ(1u, completion_sequence.size());
|
| ASSERT_EQ(1, completion_sequence[0]);
|
|
|
| - // Shutdown is asynchronous, so use ResetPool() to block until the pool is
|
| - // fully destroyed (and thus shut down).
|
| - ResetPool();
|
| + if (GetParam() == SequencedWorkerPoolRedirection::NONE) {
|
| + // Wait until the pool is fully shut down and destroyed.
|
| + ResetPool();
|
| + } else {
|
| + // Wait until the TaskScheduler is shut down.
|
| + TaskScheduler::GetInstance()->Shutdown();
|
| + }
|
|
|
| // Verify that we didn't block until the task was due.
|
| ASSERT_LT(base::Time::Now() - posted_at, TestTimeouts::action_timeout());
|
|
|
| - // Verify that the deferred task has not only not run, but has also been
|
| - // destroyed.
|
| - ASSERT_TRUE(deleted_flag->data);
|
| + // If tasks aren't redirected to the TaskScheduler, verify that the deferred
|
| + // task has not only not run, but has also been destroyed. The TaskScheduler
|
| + // doesn't destroy its tasks on shutdown.
|
| + if (GetParam() == SequencedWorkerPoolRedirection::NONE)
|
| + ASSERT_TRUE(deleted_flag->data);
|
| }
|
|
|
| // Tests that same-named tokens have the same ID.
|
| -TEST_F(SequencedWorkerPoolTest, NamedTokens) {
|
| +TEST_P(SequencedWorkerPoolTest, NamedTokens) {
|
| const std::string name1("hello");
|
| SequencedWorkerPool::SequenceToken token1 =
|
| pool()->GetNamedSequenceToken(name1);
|
| @@ -394,7 +438,7 @@ TEST_F(SequencedWorkerPoolTest, NamedTokens) {
|
|
|
| // Tests that posting a bunch of tasks (many more than the number of worker
|
| // threads) runs them all.
|
| -TEST_F(SequencedWorkerPoolTest, LotsOfTasks) {
|
| +TEST_P(SequencedWorkerPoolTest, LotsOfTasks) {
|
| pool()->PostWorkerTask(FROM_HERE,
|
| base::Bind(&TestTracker::SlowTask, tracker(), 0));
|
|
|
| @@ -412,7 +456,7 @@ TEST_F(SequencedWorkerPoolTest, LotsOfTasks) {
|
| // worker threads) to two pools simultaneously runs them all twice.
|
| // This test is meant to shake out any concurrency issues between
|
| // pools (like histograms).
|
| -TEST_F(SequencedWorkerPoolTest, LotsOfTasksTwoPools) {
|
| +TEST_P(SequencedWorkerPoolTest, LotsOfTasksTwoPools) {
|
| SequencedWorkerPoolOwner pool1(kNumWorkerThreads, "test1");
|
| SequencedWorkerPoolOwner pool2(kNumWorkerThreads, "test2");
|
|
|
| @@ -435,7 +479,7 @@ TEST_F(SequencedWorkerPoolTest, LotsOfTasksTwoPools) {
|
|
|
| // Test that tasks with the same sequence token are executed in order but don't
|
| // affect other tasks.
|
| -TEST_F(SequencedWorkerPoolTest, Sequence) {
|
| +TEST_P(SequencedWorkerPoolTest, Sequence) {
|
| // Fill all the worker threads except one.
|
| const size_t kNumBackgroundTasks = kNumWorkerThreads - 1;
|
| ThreadBlocker background_blocker;
|
| @@ -496,7 +540,7 @@ TEST_F(SequencedWorkerPoolTest, Sequence) {
|
|
|
| // Tests that any tasks posted after Shutdown are ignored.
|
| // Disabled for flakiness. See http://crbug.com/166451.
|
| -TEST_F(SequencedWorkerPoolTest, DISABLED_IgnoresAfterShutdown) {
|
| +TEST_P(SequencedWorkerPoolTest, DISABLED_IgnoresAfterShutdown) {
|
| // Start tasks to take all the threads and block them.
|
| EnsureAllWorkersCreated();
|
| ThreadBlocker blocker;
|
| @@ -543,7 +587,14 @@ TEST_F(SequencedWorkerPoolTest, DISABLED_IgnoresAfterShutdown) {
|
| ASSERT_EQ(old_has_work_call_count, has_work_call_count());
|
| }
|
|
|
| -TEST_F(SequencedWorkerPoolTest, AllowsAfterShutdown) {
|
| +TEST_P(SequencedWorkerPoolTest, AllowsAfterShutdown) {
|
| + // TaskScheduler supports posting new BLOCK_SHUTDOWN tasks during shutdown
|
| + // (see TaskSchedulerTaskTrackerTest.WillPostAndRunDuringShutdown). However,
|
| + // since it doesn't provide a way to run a callback from inside its Shutdown()
|
| + // method, it would be hard to make this test work with redirection enabled.
|
| + if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
|
| + return;
|
| +
|
| // Test that <n> new blocking tasks are allowed provided they're posted
|
| // by a running tasks.
|
| EnsureAllWorkersCreated();
|
| @@ -589,8 +640,15 @@ TEST_F(SequencedWorkerPoolTest, AllowsAfterShutdown) {
|
|
|
| // Tests that blocking tasks can still be posted during shutdown, as long as
|
| // the task is not being posted within the context of a running task.
|
| -TEST_F(SequencedWorkerPoolTest,
|
| +TEST_P(SequencedWorkerPoolTest,
|
| AllowsBlockingTasksDuringShutdownOutsideOfRunningTask) {
|
| + // TaskScheduler supports posting new BLOCK_SHUTDOWN tasks during shutdown
|
| + // (see TaskSchedulerTaskTrackerTest.WillPostAndRunDuringShutdown). However,
|
| + // since it doesn't provide a way to run a callback from inside its Shutdown()
|
| + // method, it would be hard to make this test work with redirection enabled.
|
| + if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
|
| + return;
|
| +
|
| EnsureAllWorkersCreated();
|
| ThreadBlocker blocker;
|
|
|
| @@ -617,7 +675,13 @@ TEST_F(SequencedWorkerPoolTest,
|
|
|
| // Tests that unrun tasks are discarded properly according to their shutdown
|
| // mode.
|
| -TEST_F(SequencedWorkerPoolTest, DiscardOnShutdown) {
|
| +TEST_P(SequencedWorkerPoolTest, DiscardOnShutdown) {
|
| + // Since TaskScheduler doesn't provide a way to run a callback from inside its
|
| + // Shutdown() method, it would be hard to make this test work with redirection
|
| + // enabled.
|
| + if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
|
| + return;
|
| +
|
| // Start tasks to take all the threads and block them.
|
| EnsureAllWorkersCreated();
|
| ThreadBlocker blocker;
|
| @@ -661,7 +725,7 @@ TEST_F(SequencedWorkerPoolTest, DiscardOnShutdown) {
|
| }
|
|
|
| // Tests that CONTINUE_ON_SHUTDOWN tasks don't block shutdown.
|
| -TEST_F(SequencedWorkerPoolTest, ContinueOnShutdown) {
|
| +TEST_P(SequencedWorkerPoolTest, ContinueOnShutdown) {
|
| scoped_refptr<TaskRunner> runner(pool()->GetTaskRunnerWithShutdownBehavior(
|
| SequencedWorkerPool::CONTINUE_ON_SHUTDOWN));
|
| scoped_refptr<SequencedTaskRunner> sequenced_runner(
|
| @@ -686,9 +750,16 @@ TEST_F(SequencedWorkerPoolTest, ContinueOnShutdown) {
|
|
|
| tracker()->WaitUntilTasksBlocked(3);
|
|
|
| - // This should not block. If this test hangs, it means it failed.
|
| + // Shutting down the pool should not be blocked by CONTINUE_ON_SHUTDOWN tasks.
|
| + // If this test hangs, it means it failed.
|
| + // Note: This is a no-op when redirection to the TaskScheduler is enabled.
|
| pool()->Shutdown();
|
|
|
| + // Shutting down the TaskScheduler should not be blocked by
|
| + // CONTINUE_ON_SHUTDOWN tasks.
|
| + if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
|
| + TaskScheduler::GetInstance()->Shutdown();
|
| +
|
| // The task should not have completed yet.
|
| EXPECT_EQ(0u, tracker()->WaitUntilTasksComplete(0).size());
|
|
|
| @@ -709,7 +780,13 @@ TEST_F(SequencedWorkerPoolTest, ContinueOnShutdown) {
|
|
|
| // Tests that SKIP_ON_SHUTDOWN tasks that have been started block Shutdown
|
| // until they stop, but tasks not yet started do not.
|
| -TEST_F(SequencedWorkerPoolTest, SkipOnShutdown) {
|
| +TEST_P(SequencedWorkerPoolTest, SkipOnShutdown) {
|
| + // Since TaskScheduler doesn't provide a way to run a callback from inside its
|
| + // Shutdown() method, it would be hard to make this test work with redirection
|
| + // enabled.
|
| + if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
|
| + return;
|
| +
|
| // Start tasks to take all the threads and block them.
|
| EnsureAllWorkersCreated();
|
| ThreadBlocker blocker;
|
| @@ -760,7 +837,11 @@ TEST_F(SequencedWorkerPoolTest, SkipOnShutdown) {
|
| // Ensure all worker threads are created, and then trigger a spurious
|
| // work signal. This shouldn't cause any other work signals to be
|
| // triggered. This is a regression test for http://crbug.com/117469.
|
| -TEST_F(SequencedWorkerPoolTest, SpuriousWorkSignal) {
|
| +TEST_P(SequencedWorkerPoolTest, SpuriousWorkSignal) {
|
| + // This test doesn't apply when tasks are redirected to the TaskScheduler.
|
| + if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
|
| + return;
|
| +
|
| EnsureAllWorkersCreated();
|
| int old_has_work_call_count = has_work_call_count();
|
| pool()->SignalHasWorkForTesting();
|
| @@ -773,19 +854,32 @@ void IsRunningOnCurrentThreadTask(
|
| SequencedWorkerPool::SequenceToken test_positive_token,
|
| SequencedWorkerPool::SequenceToken test_negative_token,
|
| SequencedWorkerPool* pool,
|
| - SequencedWorkerPool* unused_pool) {
|
| + SequencedWorkerPool* unused_pool,
|
| + SequencedWorkerPoolRedirection redirection) {
|
| EXPECT_TRUE(pool->RunsTasksOnCurrentThread());
|
| EXPECT_TRUE(pool->IsRunningSequenceOnCurrentThread(test_positive_token));
|
| - EXPECT_FALSE(pool->IsRunningSequenceOnCurrentThread(test_negative_token));
|
| - EXPECT_FALSE(unused_pool->RunsTasksOnCurrentThread());
|
| - EXPECT_FALSE(
|
| - unused_pool->IsRunningSequenceOnCurrentThread(test_positive_token));
|
| - EXPECT_FALSE(
|
| - unused_pool->IsRunningSequenceOnCurrentThread(test_negative_token));
|
| +
|
| + if (redirection == SequencedWorkerPoolRedirection::NONE) {
|
| + // Tasks posted to different pools may run on the same threads when
|
| + // redirection to the TaskScheduler is enabled.
|
| + EXPECT_FALSE(unused_pool->RunsTasksOnCurrentThread());
|
| +
|
| + // TODO(gab): When redirection to the TaskScheduler is enabled,
|
| + // IsRunningSequenceOnCurrentThread() returns true if a task bound to the
|
| + // provided sequence token *could* run on the current thread. Once the
|
| + // method is fixed to return true only when called from a thread that is
|
| + // *currently running* a task bound to the provided sequence token, move
|
| + // these tests out of the conditional.
|
| + EXPECT_FALSE(pool->IsRunningSequenceOnCurrentThread(test_negative_token));
|
| + EXPECT_FALSE(
|
| + unused_pool->IsRunningSequenceOnCurrentThread(test_positive_token));
|
| + EXPECT_FALSE(
|
| + unused_pool->IsRunningSequenceOnCurrentThread(test_negative_token));
|
| + }
|
| }
|
|
|
| // Verify correctness of the IsRunningSequenceOnCurrentThread method.
|
| -TEST_F(SequencedWorkerPoolTest, IsRunningOnCurrentThread) {
|
| +TEST_P(SequencedWorkerPoolTest, IsRunningOnCurrentThread) {
|
| SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken();
|
| SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken();
|
| SequencedWorkerPool::SequenceToken unsequenced_token;
|
| @@ -808,22 +902,28 @@ TEST_F(SequencedWorkerPoolTest, IsRunningOnCurrentThread) {
|
| token1, FROM_HERE,
|
| base::Bind(&IsRunningOnCurrentThreadTask, token1, token2,
|
| base::RetainedRef(pool()),
|
| - base::RetainedRef(unused_pool_owner.pool())));
|
| + base::RetainedRef(unused_pool_owner.pool()), GetParam()));
|
| pool()->PostSequencedWorkerTask(
|
| token2, FROM_HERE,
|
| base::Bind(&IsRunningOnCurrentThreadTask, token2, unsequenced_token,
|
| base::RetainedRef(pool()),
|
| - base::RetainedRef(unused_pool_owner.pool())));
|
| + base::RetainedRef(unused_pool_owner.pool()), GetParam()));
|
| pool()->PostWorkerTask(
|
| - FROM_HERE, base::Bind(&IsRunningOnCurrentThreadTask, unsequenced_token,
|
| - token1, base::RetainedRef(pool()),
|
| - base::RetainedRef(unused_pool_owner.pool())));
|
| + FROM_HERE,
|
| + base::Bind(&IsRunningOnCurrentThreadTask, unsequenced_token, token1,
|
| + base::RetainedRef(pool()),
|
| + base::RetainedRef(unused_pool_owner.pool()), GetParam()));
|
| }
|
|
|
| // Checks that tasks are destroyed in the right context during shutdown. If a
|
| // task is destroyed while SequencedWorkerPool's global lock is held,
|
| // SequencedWorkerPool might deadlock.
|
| -TEST_F(SequencedWorkerPoolTest, AvoidsDeadlockOnShutdown) {
|
| +TEST_P(SequencedWorkerPoolTest, AvoidsDeadlockOnShutdown) {
|
| + // Since the TaskScheduler doesn't delete pending tasks on shutdown, this test
|
| + // doesn't apply when tasks are redirected to the TaskScheduler.
|
| + if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
|
| + return;
|
| +
|
| for (int i = 0; i < 4; ++i) {
|
| scoped_refptr<DestructionDeadlockChecker> checker(
|
| new DestructionDeadlockChecker(pool()));
|
| @@ -837,8 +937,13 @@ TEST_F(SequencedWorkerPoolTest, AvoidsDeadlockOnShutdown) {
|
|
|
| // Similar to the test AvoidsDeadlockOnShutdown, but there are now also
|
| // sequenced, blocking tasks in the queue during shutdown.
|
| -TEST_F(SequencedWorkerPoolTest,
|
| +TEST_P(SequencedWorkerPoolTest,
|
| AvoidsDeadlockOnShutdownWithSequencedBlockingTasks) {
|
| + // Since the TaskScheduler doesn't delete pending tasks on shutdown, this test
|
| + // doesn't apply when tasks are redirected to the TaskScheduler.
|
| + if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
|
| + return;
|
| +
|
| const std::string sequence_token_name("name");
|
| for (int i = 0; i < 4; ++i) {
|
| scoped_refptr<DestructionDeadlockChecker> checker(
|
| @@ -856,7 +961,12 @@ TEST_F(SequencedWorkerPoolTest,
|
| }
|
|
|
| // Verify that FlushForTesting works as intended.
|
| -TEST_F(SequencedWorkerPoolTest, FlushForTesting) {
|
| +TEST_P(SequencedWorkerPoolTest, FlushForTesting) {
|
| + // FlushForTesting cannot be called when tasks are redirected to the
|
| + // TaskScheduler.
|
| + if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
|
| + return;
|
| +
|
| // Should be fine to call on a new instance.
|
| pool()->FlushForTesting();
|
|
|
| @@ -895,6 +1005,15 @@ TEST_F(SequencedWorkerPoolTest, FlushForTesting) {
|
| pool()->FlushForTesting();
|
| }
|
|
|
| +INSTANTIATE_TEST_CASE_P(
|
| + NoRedirection,
|
| + SequencedWorkerPoolTest,
|
| + ::testing::Values(SequencedWorkerPoolRedirection::NONE));
|
| +INSTANTIATE_TEST_CASE_P(
|
| + RedirectionToTaskScheduler,
|
| + SequencedWorkerPoolTest,
|
| + ::testing::Values(SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER));
|
| +
|
| namespace {
|
|
|
| void CheckWorkerPoolAndSequenceToken(
|
| @@ -911,7 +1030,14 @@ void CheckWorkerPoolAndSequenceToken(
|
|
|
| } // namespace
|
|
|
| -TEST_F(SequencedWorkerPoolTest, GetWorkerPoolAndSequenceTokenForCurrentThread) {
|
| +TEST_P(SequencedWorkerPoolTest, GetWorkerPoolAndSequenceTokenForCurrentThread) {
|
| + // SequencedWorkerPool::GetSequenceTokenForCurrentThread() isn't supported
|
| + // when tasks are redirected to the TaskScheduler. It will never be supported
|
| + // since its only uses are in SequencedTaskRunnerHandle and
|
| + // SequenceCheckerImpl which don't need it when redirection is enabled.
|
| + if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
|
| + return;
|
| +
|
| EnsureAllWorkersCreated();
|
|
|
| // The current thread should have neither a worker pool nor a sequence token.
|
| @@ -938,16 +1064,7 @@ TEST_F(SequencedWorkerPoolTest, GetWorkerPoolAndSequenceTokenForCurrentThread) {
|
| pool()->FlushForTesting();
|
| }
|
|
|
| -TEST_F(SequencedWorkerPoolTest, ShutsDownCleanWithContinueOnShutdown) {
|
| - scoped_refptr<SequencedTaskRunner> task_runner =
|
| - pool()->GetSequencedTaskRunnerWithShutdownBehavior(
|
| - pool()->GetSequenceToken(),
|
| - base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
|
| -
|
| - // Upon test exit, should shut down without hanging.
|
| - pool()->Shutdown();
|
| -}
|
| -
|
| +template <SequencedWorkerPoolRedirection redirection>
|
| class SequencedWorkerPoolTaskRunnerTestDelegate {
|
| public:
|
| SequencedWorkerPoolTaskRunnerTestDelegate() {}
|
| @@ -955,8 +1072,11 @@ class SequencedWorkerPoolTaskRunnerTestDelegate {
|
| ~SequencedWorkerPoolTaskRunnerTestDelegate() {}
|
|
|
| void StartTaskRunner() {
|
| - pool_owner_.reset(
|
| - new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest"));
|
| + pool_owner_.reset(new SequencedWorkerPoolOwner(
|
| + kNumWorkerThreads, "SequencedWorkerPoolTaskRunnerTest"));
|
| +
|
| + if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
|
| + StartRedirectionToTaskScheduler(kNumWorkerThreads);
|
| }
|
|
|
| scoped_refptr<SequencedWorkerPool> GetTaskRunner() {
|
| @@ -964,12 +1084,16 @@ class SequencedWorkerPoolTaskRunnerTestDelegate {
|
| }
|
|
|
| void StopTaskRunner() {
|
| - // Make sure all tasks are run before shutting down. Delayed tasks are
|
| - // not run, they're simply deleted.
|
| - pool_owner_->pool()->FlushForTesting();
|
| - pool_owner_->pool()->Shutdown();
|
| - // Don't reset |pool_owner_| here, as the test may still hold a
|
| - // reference to the pool.
|
| + pool_owner_->pool()->Shutdown(kNumAllowedBlockShutdownTasks);
|
| + if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) {
|
| + // When redirection to the TaskScheduler is enabled, shutting down the
|
| + // pool is a no-op. It is necessary to shut down the TaskScheduler to make
|
| + // sure that all tasks have been executed.
|
| + TaskScheduler::GetInstance()->Shutdown();
|
| + StopRedirectionToTaskScheduler();
|
| + }
|
| + // Don't reset |pool_owner_| here, as the test may still hold a reference to
|
| + // the pool.
|
| }
|
|
|
| private:
|
| @@ -977,12 +1101,26 @@ class SequencedWorkerPoolTaskRunnerTestDelegate {
|
| std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_;
|
| };
|
|
|
| +INSTANTIATE_TYPED_TEST_CASE_P(SequencedWorkerPool,
|
| + TaskRunnerTest,
|
| + SequencedWorkerPoolTaskRunnerTestDelegate<
|
| + SequencedWorkerPoolRedirection::NONE>);
|
| +INSTANTIATE_TYPED_TEST_CASE_P(SequencedWorkerPool,
|
| + TaskRunnerAffinityTest,
|
| + SequencedWorkerPoolTaskRunnerTestDelegate<
|
| + SequencedWorkerPoolRedirection::NONE>);
|
| INSTANTIATE_TYPED_TEST_CASE_P(
|
| - SequencedWorkerPool, TaskRunnerTest,
|
| - SequencedWorkerPoolTaskRunnerTestDelegate);
|
| -INSTANTIATE_TYPED_TEST_CASE_P(SequencedWorkerPool, TaskRunnerAffinityTest,
|
| - SequencedWorkerPoolTaskRunnerTestDelegate);
|
| + SequencedWorkerPoolToTaskScheduler,
|
| + TaskRunnerTest,
|
| + SequencedWorkerPoolTaskRunnerTestDelegate<
|
| + SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER>);
|
| +INSTANTIATE_TYPED_TEST_CASE_P(
|
| + SequencedWorkerPoolToTaskScheduler,
|
| + TaskRunnerAffinityTest,
|
| + SequencedWorkerPoolTaskRunnerTestDelegate<
|
| + SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER>);
|
|
|
| +template <SequencedWorkerPoolRedirection redirection>
|
| class SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate {
|
| public:
|
| SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate() {}
|
| @@ -991,10 +1129,13 @@ class SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate {
|
| }
|
|
|
| void StartTaskRunner() {
|
| - pool_owner_.reset(
|
| - new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest"));
|
| + pool_owner_.reset(new SequencedWorkerPoolOwner(
|
| + kNumWorkerThreads, "SequencedWorkerPoolSequencedTaskRunnerTest"));
|
| task_runner_ = pool_owner_->pool()->GetTaskRunnerWithShutdownBehavior(
|
| SequencedWorkerPool::BLOCK_SHUTDOWN);
|
| +
|
| + if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
|
| + StartRedirectionToTaskScheduler(kNumWorkerThreads);
|
| }
|
|
|
| scoped_refptr<TaskRunner> GetTaskRunner() {
|
| @@ -1002,12 +1143,16 @@ class SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate {
|
| }
|
|
|
| void StopTaskRunner() {
|
| - // Make sure all tasks are run before shutting down. Delayed tasks are
|
| - // not run, they're simply deleted.
|
| - pool_owner_->pool()->FlushForTesting();
|
| - pool_owner_->pool()->Shutdown();
|
| - // Don't reset |pool_owner_| here, as the test may still hold a
|
| - // reference to the pool.
|
| + pool_owner_->pool()->Shutdown(kNumAllowedBlockShutdownTasks);
|
| + if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) {
|
| + // When redirection to the TaskScheduler is enabled, shutting down the
|
| + // pool is a no-op. It is necessary to shut down the TaskScheduler to make
|
| + // sure that all tasks have been executed.
|
| + TaskScheduler::GetInstance()->Shutdown();
|
| + StopRedirectionToTaskScheduler();
|
| + }
|
| + // Don't reset |pool_owner_| here, as the test may still hold a reference to
|
| + // the pool.
|
| }
|
|
|
| private:
|
| @@ -1017,12 +1162,27 @@ class SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate {
|
| };
|
|
|
| INSTANTIATE_TYPED_TEST_CASE_P(
|
| - SequencedWorkerPoolTaskRunner, TaskRunnerTest,
|
| - SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate);
|
| + SequencedWorkerPoolTaskRunner,
|
| + TaskRunnerTest,
|
| + SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate<
|
| + SequencedWorkerPoolRedirection::NONE>);
|
| +INSTANTIATE_TYPED_TEST_CASE_P(
|
| + SequencedWorkerPoolTaskRunner,
|
| + TaskRunnerAffinityTest,
|
| + SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate<
|
| + SequencedWorkerPoolRedirection::NONE>);
|
| +INSTANTIATE_TYPED_TEST_CASE_P(
|
| + SequencedWorkerPoolTaskRunnerToTaskScheduler,
|
| + TaskRunnerTest,
|
| + SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate<
|
| + SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER>);
|
| INSTANTIATE_TYPED_TEST_CASE_P(
|
| - SequencedWorkerPoolTaskRunner, TaskRunnerAffinityTest,
|
| - SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate);
|
| + SequencedWorkerPoolTaskRunnerToTaskScheduler,
|
| + TaskRunnerAffinityTest,
|
| + SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate<
|
| + SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER>);
|
|
|
| +template <SequencedWorkerPoolRedirection redirection>
|
| class SequencedWorkerPoolSequencedTaskRunnerTestDelegate {
|
| public:
|
| SequencedWorkerPoolSequencedTaskRunnerTestDelegate() {}
|
| @@ -1032,9 +1192,12 @@ class SequencedWorkerPoolSequencedTaskRunnerTestDelegate {
|
|
|
| void StartTaskRunner() {
|
| pool_owner_.reset(new SequencedWorkerPoolOwner(
|
| - 10, "SequencedWorkerPoolSequencedTaskRunnerTest"));
|
| + kNumWorkerThreads, "SequencedWorkerPoolSequencedTaskRunnerTest"));
|
| task_runner_ = pool_owner_->pool()->GetSequencedTaskRunner(
|
| pool_owner_->pool()->GetSequenceToken());
|
| +
|
| + if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
|
| + StartRedirectionToTaskScheduler(kNumWorkerThreads);
|
| }
|
|
|
| scoped_refptr<SequencedTaskRunner> GetTaskRunner() {
|
| @@ -1042,12 +1205,16 @@ class SequencedWorkerPoolSequencedTaskRunnerTestDelegate {
|
| }
|
|
|
| void StopTaskRunner() {
|
| - // Make sure all tasks are run before shutting down. Delayed tasks are
|
| - // not run, they're simply deleted.
|
| - pool_owner_->pool()->FlushForTesting();
|
| - pool_owner_->pool()->Shutdown();
|
| - // Don't reset |pool_owner_| here, as the test may still hold a
|
| - // reference to the pool.
|
| + pool_owner_->pool()->Shutdown(kNumAllowedBlockShutdownTasks);
|
| + if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) {
|
| + // When redirection to the TaskScheduler is enabled, shutting down the
|
| + // pool is a no-op. It is necessary to shut down the TaskScheduler to make
|
| + // sure that all tasks have been executed.
|
| + TaskScheduler::GetInstance()->Shutdown();
|
| + StopRedirectionToTaskScheduler();
|
| + }
|
| + // Don't reset |pool_owner_| here, as the test may still hold a reference to
|
| + // the pool.
|
| }
|
|
|
| private:
|
| @@ -1057,19 +1224,37 @@ class SequencedWorkerPoolSequencedTaskRunnerTestDelegate {
|
| };
|
|
|
| INSTANTIATE_TYPED_TEST_CASE_P(
|
| - SequencedWorkerPoolSequencedTaskRunner, TaskRunnerTest,
|
| - SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
|
| + SequencedWorkerPoolSequencedTaskRunner,
|
| + TaskRunnerTest,
|
| + SequencedWorkerPoolSequencedTaskRunnerTestDelegate<
|
| + SequencedWorkerPoolRedirection::NONE>);
|
| +INSTANTIATE_TYPED_TEST_CASE_P(
|
| + SequencedWorkerPoolSequencedTaskRunner,
|
| + TaskRunnerAffinityTest,
|
| + SequencedWorkerPoolSequencedTaskRunnerTestDelegate<
|
| + SequencedWorkerPoolRedirection::NONE>);
|
| INSTANTIATE_TYPED_TEST_CASE_P(
|
| - SequencedWorkerPoolSequencedTaskRunner, TaskRunnerAffinityTest,
|
| - SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
|
| + SequencedWorkerPoolSequencedTaskRunnerToTaskScheduler,
|
| + TaskRunnerAffinityTest,
|
| + SequencedWorkerPoolSequencedTaskRunnerTestDelegate<
|
| + SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER>);
|
|
|
| INSTANTIATE_TYPED_TEST_CASE_P(
|
| - SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest,
|
| - SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
|
| + SequencedWorkerPoolSequencedTaskRunner,
|
| + SequencedTaskRunnerTest,
|
| + SequencedWorkerPoolSequencedTaskRunnerTestDelegate<
|
| + SequencedWorkerPoolRedirection::NONE>);
|
| INSTANTIATE_TYPED_TEST_CASE_P(
|
| SequencedWorkerPoolSequencedTaskRunner,
|
| SequencedTaskRunnerDelayedTest,
|
| - SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
|
| + SequencedWorkerPoolSequencedTaskRunnerTestDelegate<
|
| + SequencedWorkerPoolRedirection::NONE>);
|
| +
|
| +// Don't run TaskRunnerTest, SequencedTaskRunnerTest and
|
| +// SequencedTaskRunnerDelayedTest with sequenced tasks redirected to the
|
| +// TaskScheduler. These tests post tasks with and without delays which result in
|
| +// getting tasks with different shutdown behaviors in the same sequence. That
|
| +// isn't supported by the TaskScheduler.
|
|
|
| } // namespace
|
|
|
|
|