Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/threading/sequenced_worker_pool.h" | 5 #include "base/threading/sequenced_worker_pool.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <memory> | 10 #include <memory> |
| 11 #include <utility> | |
| 11 | 12 |
| 12 #include "base/bind.h" | 13 #include "base/bind.h" |
| 13 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" |
| 14 #include "base/macros.h" | 15 #include "base/macros.h" |
| 15 #include "base/memory/ref_counted.h" | 16 #include "base/memory/ref_counted.h" |
| 16 #include "base/message_loop/message_loop.h" | 17 #include "base/message_loop/message_loop.h" |
| 17 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
| 18 #include "base/synchronization/condition_variable.h" | 19 #include "base/synchronization/condition_variable.h" |
| 19 #include "base/synchronization/lock.h" | 20 #include "base/synchronization/lock.h" |
| 21 #include "base/task_scheduler/scheduler_worker_pool_params.h" | |
| 22 #include "base/task_scheduler/task_scheduler.h" | |
| 23 #include "base/task_scheduler/task_scheduler_impl.h" | |
| 20 #include "base/test/sequenced_task_runner_test_template.h" | 24 #include "base/test/sequenced_task_runner_test_template.h" |
| 21 #include "base/test/sequenced_worker_pool_owner.h" | 25 #include "base/test/sequenced_worker_pool_owner.h" |
| 22 #include "base/test/task_runner_test_template.h" | 26 #include "base/test/task_runner_test_template.h" |
| 23 #include "base/test/test_timeouts.h" | 27 #include "base/test/test_timeouts.h" |
| 24 #include "base/threading/platform_thread.h" | 28 #include "base/threading/platform_thread.h" |
| 29 #include "base/threading/thread_checker_impl.h" | |
| 25 #include "base/time/time.h" | 30 #include "base/time/time.h" |
| 26 #include "base/tracked_objects.h" | 31 #include "base/tracked_objects.h" |
| 27 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
| 28 | 33 |
| 29 namespace base { | 34 namespace base { |
| 30 | 35 |
| 31 // IMPORTANT NOTE: | 36 // IMPORTANT NOTE: |
| 32 // | 37 // |
| 33 // Many of these tests have failure modes where they'll hang forever. These | 38 // Many of these tests have failure modes where they'll hang forever. These |
| 34 // tests should not be flaky, and hanging indicates a type of failure. Do not | 39 // tests should not be flaky, and hanging indicates a type of failure. Do not |
| 35 // mark as flaky if they're hanging, it's likely an actual bug. | 40 // mark as flaky if they're hanging, it's likely an actual bug. |
| 36 | 41 |
| 37 namespace { | 42 namespace { |
| 38 | 43 |
| 39 const size_t kNumWorkerThreads = 3; | 44 constexpr size_t kNumWorkerThreads = 3; |
| 45 constexpr size_t kNumAllowedBlockShutdownTasks = 1000; | |
| 40 | 46 |
| 41 // Allows a number of threads to all be blocked on the same event, and | 47 // Allows a number of threads to all be blocked on the same event, and |
| 42 // provides a way to unblock a certain number of them. | 48 // provides a way to unblock a certain number of them. |
| 43 class ThreadBlocker { | 49 class ThreadBlocker { |
| 44 public: | 50 public: |
| 45 ThreadBlocker() : lock_(), cond_var_(&lock_), unblock_counter_(0) {} | 51 ThreadBlocker() : lock_(), cond_var_(&lock_), unblock_counter_(0) {} |
| 46 | 52 |
| 47 void Block() { | 53 void Block() { |
| 48 { | 54 { |
| 49 base::AutoLock lock(lock_); | 55 base::AutoLock lock(lock_); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 224 | 230 |
| 225 base::ConditionVariable cond_var_; | 231 base::ConditionVariable cond_var_; |
| 226 | 232 |
| 227 // Protected by lock_. | 233 // Protected by lock_. |
| 228 std::vector<int> complete_sequence_; | 234 std::vector<int> complete_sequence_; |
| 229 | 235 |
| 230 // Counter of the number of "block" workers that have started. | 236 // Counter of the number of "block" workers that have started. |
| 231 size_t started_events_; | 237 size_t started_events_; |
| 232 }; | 238 }; |
| 233 | 239 |
| 234 class SequencedWorkerPoolTest : public testing::Test { | 240 enum class SequencedWorkerPoolRedirection { NONE, TO_TASK_SCHEDULER }; |
| 241 | |
| 242 void StartRedirectionToTaskScheduler(size_t num_threads) { | |
| 243 std::vector<SchedulerWorkerPoolParams> worker_pool_params; | |
| 244 worker_pool_params.emplace_back( | |
| 245 "SchedulerWorkerPoolName", ThreadPriority::NORMAL, | |
| 246 SchedulerWorkerPoolParams::IORestriction::ALLOWED, num_threads, | |
| 247 TimeDelta::Max()); | |
| 248 TaskScheduler::CreateAndSetDefaultTaskScheduler( | |
| 249 std::move(worker_pool_params), | |
| 250 base::Bind([](const TaskTraits&) -> size_t { return 0U; })); | |
| 251 SequencedWorkerPool::ResetRedirectToTaskSchedulerForProcessForTesting(); | |
| 252 SequencedWorkerPool::RedirectToTaskSchedulerForProcess(); | |
| 253 } | |
| 254 | |
| 255 void StopRedirectionToTaskScheduler() { | |
| 256 SequencedWorkerPool::ResetRedirectToTaskSchedulerForProcessForTesting(); | |
| 257 static_cast<internal::TaskSchedulerImpl*>(TaskScheduler::GetInstance()) | |
| 258 ->JoinForTesting(); | |
| 259 TaskScheduler::SetInstance(nullptr); | |
| 260 } | |
| 261 | |
| 262 class SequencedWorkerPoolTest | |
| 263 : public testing::TestWithParam<SequencedWorkerPoolRedirection> { | |
| 235 public: | 264 public: |
| 236 SequencedWorkerPoolTest() | 265 SequencedWorkerPoolTest() |
| 237 : tracker_(new TestTracker) { | 266 : tracker_(new TestTracker) { |
| 238 ResetPool(); | 267 ResetPool(); |
| 239 } | 268 } |
| 240 | 269 |
| 270 void SetUp() override { | |
| 271 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 272 StartRedirectionToTaskScheduler(kNumWorkerThreads); | |
| 273 } | |
| 274 | |
| 275 void TearDown() override { | |
| 276 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 277 StopRedirectionToTaskScheduler(); | |
| 278 } | |
| 279 | |
| 241 const scoped_refptr<SequencedWorkerPool>& pool() { | 280 const scoped_refptr<SequencedWorkerPool>& pool() { |
| 242 return pool_owner_->pool(); | 281 return pool_owner_->pool(); |
| 243 } | 282 } |
| 244 TestTracker* tracker() { return tracker_.get(); } | 283 TestTracker* tracker() { return tracker_.get(); } |
| 245 | 284 |
| 246 // Destroys the SequencedWorkerPool instance, blocking until it is fully shut | 285 // Destroys the SequencedWorkerPool instance, blocking until it is fully shut |
| 247 // down, and creates a new instance. | 286 // down, and creates a new instance. |
| 248 void ResetPool() { | 287 void ResetPool() { |
| 249 pool_owner_.reset(new SequencedWorkerPoolOwner(kNumWorkerThreads, "test")); | 288 pool_owner_.reset(new SequencedWorkerPoolOwner(kNumWorkerThreads, "test")); |
| 250 } | 289 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 325 const scoped_refptr<base::RefCountedData<bool> > deleted_flag_; | 364 const scoped_refptr<base::RefCountedData<bool> > deleted_flag_; |
| 326 DISALLOW_COPY_AND_ASSIGN(DeletionHelper); | 365 DISALLOW_COPY_AND_ASSIGN(DeletionHelper); |
| 327 }; | 366 }; |
| 328 | 367 |
| 329 void HoldPoolReference(const scoped_refptr<base::SequencedWorkerPool>& pool, | 368 void HoldPoolReference(const scoped_refptr<base::SequencedWorkerPool>& pool, |
| 330 const scoped_refptr<DeletionHelper>& helper) { | 369 const scoped_refptr<DeletionHelper>& helper) { |
| 331 ADD_FAILURE() << "Should never run"; | 370 ADD_FAILURE() << "Should never run"; |
| 332 } | 371 } |
| 333 | 372 |
| 334 // Tests that delayed tasks are deleted upon shutdown of the pool. | 373 // Tests that delayed tasks are deleted upon shutdown of the pool. |
| 335 TEST_F(SequencedWorkerPoolTest, DelayedTaskDuringShutdown) { | 374 TEST_P(SequencedWorkerPoolTest, DelayedTaskDuringShutdown) { |
| 336 // Post something to verify the pool is started up. | 375 // Post something to verify the pool is started up. |
| 337 EXPECT_TRUE(pool()->PostTask( | 376 EXPECT_TRUE(pool()->PostTask( |
| 338 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 1))); | 377 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 1))); |
| 339 | 378 |
| 340 scoped_refptr<base::RefCountedData<bool> > deleted_flag( | 379 scoped_refptr<base::RefCountedData<bool> > deleted_flag( |
| 341 new base::RefCountedData<bool>(false)); | 380 new base::RefCountedData<bool>(false)); |
| 342 | 381 |
| 343 base::Time posted_at(base::Time::Now()); | 382 base::Time posted_at(base::Time::Now()); |
| 344 // Post something that shouldn't run. | 383 // Post something that shouldn't run. |
| 345 EXPECT_TRUE(pool()->PostDelayedTask( | 384 EXPECT_TRUE(pool()->PostDelayedTask( |
| 346 FROM_HERE, | 385 FROM_HERE, |
| 347 base::Bind(&HoldPoolReference, | 386 base::Bind(&HoldPoolReference, |
| 348 pool(), | 387 pool(), |
| 349 make_scoped_refptr(new DeletionHelper(deleted_flag))), | 388 make_scoped_refptr(new DeletionHelper(deleted_flag))), |
| 350 TestTimeouts::action_timeout())); | 389 TestTimeouts::action_timeout())); |
| 351 | 390 |
| 352 std::vector<int> completion_sequence = tracker()->WaitUntilTasksComplete(1); | 391 std::vector<int> completion_sequence = tracker()->WaitUntilTasksComplete(1); |
| 353 ASSERT_EQ(1u, completion_sequence.size()); | 392 ASSERT_EQ(1u, completion_sequence.size()); |
| 354 ASSERT_EQ(1, completion_sequence[0]); | 393 ASSERT_EQ(1, completion_sequence[0]); |
| 355 | 394 |
| 356 // Shutdown is asynchronous, so use ResetPool() to block until the pool is | 395 if (GetParam() == SequencedWorkerPoolRedirection::NONE) { |
| 357 // fully destroyed (and thus shut down). | 396 // Wait until the pool is fully shut down and destroyed. |
| 358 ResetPool(); | 397 ResetPool(); |
| 398 } else { | |
| 399 // Wait until the TaskScheduler is shut down. | |
| 400 TaskScheduler::GetInstance()->Shutdown(); | |
| 401 } | |
| 359 | 402 |
| 360 // Verify that we didn't block until the task was due. | 403 // Verify that we didn't block until the task was due. |
| 361 ASSERT_LT(base::Time::Now() - posted_at, TestTimeouts::action_timeout()); | 404 ASSERT_LT(base::Time::Now() - posted_at, TestTimeouts::action_timeout()); |
| 362 | 405 |
| 363 // Verify that the deferred task has not only not run, but has also been | 406 // If tasks aren't redirected to the TaskScheduler, verify that the deferred |
| 364 // destroyed. | 407 // task has not only not run, but has also been destroyed. The TaskScheduler |
|
danakj
2016/09/01 23:16:34
This isn't checking that the task was run tho with
| |
| 365 ASSERT_TRUE(deleted_flag->data); | 408 // doesn't destroy its tasks on shutdown. |
| 409 if (GetParam() == SequencedWorkerPoolRedirection::NONE) | |
| 410 ASSERT_TRUE(deleted_flag->data); | |
| 366 } | 411 } |
| 367 | 412 |
| 368 // Tests that same-named tokens have the same ID. | 413 // Tests that same-named tokens have the same ID. |
| 369 TEST_F(SequencedWorkerPoolTest, NamedTokens) { | 414 TEST_P(SequencedWorkerPoolTest, NamedTokens) { |
| 370 const std::string name1("hello"); | 415 const std::string name1("hello"); |
| 371 SequencedWorkerPool::SequenceToken token1 = | 416 SequencedWorkerPool::SequenceToken token1 = |
| 372 pool()->GetNamedSequenceToken(name1); | 417 pool()->GetNamedSequenceToken(name1); |
| 373 | 418 |
| 374 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken(); | 419 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken(); |
| 375 | 420 |
| 376 const std::string name3("goodbye"); | 421 const std::string name3("goodbye"); |
| 377 SequencedWorkerPool::SequenceToken token3 = | 422 SequencedWorkerPool::SequenceToken token3 = |
| 378 pool()->GetNamedSequenceToken(name3); | 423 pool()->GetNamedSequenceToken(name3); |
| 379 | 424 |
| 380 // All 3 tokens should be different. | 425 // All 3 tokens should be different. |
| 381 EXPECT_FALSE(token1.Equals(token2)); | 426 EXPECT_FALSE(token1.Equals(token2)); |
| 382 EXPECT_FALSE(token1.Equals(token3)); | 427 EXPECT_FALSE(token1.Equals(token3)); |
| 383 EXPECT_FALSE(token2.Equals(token3)); | 428 EXPECT_FALSE(token2.Equals(token3)); |
| 384 | 429 |
| 385 // Requesting the same name again should give the same value. | 430 // Requesting the same name again should give the same value. |
| 386 SequencedWorkerPool::SequenceToken token1again = | 431 SequencedWorkerPool::SequenceToken token1again = |
| 387 pool()->GetNamedSequenceToken(name1); | 432 pool()->GetNamedSequenceToken(name1); |
| 388 EXPECT_TRUE(token1.Equals(token1again)); | 433 EXPECT_TRUE(token1.Equals(token1again)); |
| 389 | 434 |
| 390 SequencedWorkerPool::SequenceToken token3again = | 435 SequencedWorkerPool::SequenceToken token3again = |
| 391 pool()->GetNamedSequenceToken(name3); | 436 pool()->GetNamedSequenceToken(name3); |
| 392 EXPECT_TRUE(token3.Equals(token3again)); | 437 EXPECT_TRUE(token3.Equals(token3again)); |
| 393 } | 438 } |
| 394 | 439 |
| 395 // Tests that posting a bunch of tasks (many more than the number of worker | 440 // Tests that posting a bunch of tasks (many more than the number of worker |
| 396 // threads) runs them all. | 441 // threads) runs them all. |
| 397 TEST_F(SequencedWorkerPoolTest, LotsOfTasks) { | 442 TEST_P(SequencedWorkerPoolTest, LotsOfTasks) { |
| 398 pool()->PostWorkerTask(FROM_HERE, | 443 pool()->PostWorkerTask(FROM_HERE, |
| 399 base::Bind(&TestTracker::SlowTask, tracker(), 0)); | 444 base::Bind(&TestTracker::SlowTask, tracker(), 0)); |
| 400 | 445 |
| 401 const size_t kNumTasks = 20; | 446 const size_t kNumTasks = 20; |
| 402 for (size_t i = 1; i < kNumTasks; i++) { | 447 for (size_t i = 1; i < kNumTasks; i++) { |
| 403 pool()->PostWorkerTask(FROM_HERE, | 448 pool()->PostWorkerTask(FROM_HERE, |
| 404 base::Bind(&TestTracker::FastTask, tracker(), i)); | 449 base::Bind(&TestTracker::FastTask, tracker(), i)); |
| 405 } | 450 } |
| 406 | 451 |
| 407 std::vector<int> result = tracker()->WaitUntilTasksComplete(kNumTasks); | 452 std::vector<int> result = tracker()->WaitUntilTasksComplete(kNumTasks); |
| 408 EXPECT_EQ(kNumTasks, result.size()); | 453 EXPECT_EQ(kNumTasks, result.size()); |
| 409 } | 454 } |
| 410 | 455 |
| 411 // Tests that posting a bunch of tasks (many more than the number of | 456 // Tests that posting a bunch of tasks (many more than the number of |
| 412 // worker threads) to two pools simultaneously runs them all twice. | 457 // worker threads) to two pools simultaneously runs them all twice. |
| 413 // This test is meant to shake out any concurrency issues between | 458 // This test is meant to shake out any concurrency issues between |
| 414 // pools (like histograms). | 459 // pools (like histograms). |
| 415 TEST_F(SequencedWorkerPoolTest, LotsOfTasksTwoPools) { | 460 TEST_P(SequencedWorkerPoolTest, LotsOfTasksTwoPools) { |
| 416 SequencedWorkerPoolOwner pool1(kNumWorkerThreads, "test1"); | 461 SequencedWorkerPoolOwner pool1(kNumWorkerThreads, "test1"); |
| 417 SequencedWorkerPoolOwner pool2(kNumWorkerThreads, "test2"); | 462 SequencedWorkerPoolOwner pool2(kNumWorkerThreads, "test2"); |
| 418 | 463 |
| 419 base::Closure slow_task = base::Bind(&TestTracker::SlowTask, tracker(), 0); | 464 base::Closure slow_task = base::Bind(&TestTracker::SlowTask, tracker(), 0); |
| 420 pool1.pool()->PostWorkerTask(FROM_HERE, slow_task); | 465 pool1.pool()->PostWorkerTask(FROM_HERE, slow_task); |
| 421 pool2.pool()->PostWorkerTask(FROM_HERE, slow_task); | 466 pool2.pool()->PostWorkerTask(FROM_HERE, slow_task); |
| 422 | 467 |
| 423 const size_t kNumTasks = 20; | 468 const size_t kNumTasks = 20; |
| 424 for (size_t i = 1; i < kNumTasks; i++) { | 469 for (size_t i = 1; i < kNumTasks; i++) { |
| 425 base::Closure fast_task = | 470 base::Closure fast_task = |
| 426 base::Bind(&TestTracker::FastTask, tracker(), i); | 471 base::Bind(&TestTracker::FastTask, tracker(), i); |
| 427 pool1.pool()->PostWorkerTask(FROM_HERE, fast_task); | 472 pool1.pool()->PostWorkerTask(FROM_HERE, fast_task); |
| 428 pool2.pool()->PostWorkerTask(FROM_HERE, fast_task); | 473 pool2.pool()->PostWorkerTask(FROM_HERE, fast_task); |
| 429 } | 474 } |
| 430 | 475 |
| 431 std::vector<int> result = | 476 std::vector<int> result = |
| 432 tracker()->WaitUntilTasksComplete(2*kNumTasks); | 477 tracker()->WaitUntilTasksComplete(2*kNumTasks); |
| 433 EXPECT_EQ(2 * kNumTasks, result.size()); | 478 EXPECT_EQ(2 * kNumTasks, result.size()); |
| 434 } | 479 } |
| 435 | 480 |
| 481 namespace { | |
| 482 void ExpectCalledOnValidThread(ThreadCheckerImpl* thread_checker) { | |
| 483 EXPECT_TRUE(thread_checker->CalledOnValidThread()); | |
| 484 } | |
| 485 } // namespace | |
| 486 | |
| 487 // Tests that all tasks posted to a single-thread pool run on the same thread. | |
| 488 TEST_P(SequencedWorkerPoolTest, SingleThreaded) { | |
| 489 SequencedWorkerPoolOwner single_threaded_pool(1, "SingleThreadedPool"); | |
| 490 | |
| 491 ThreadCheckerImpl thread_checker; | |
| 492 thread_checker.DetachFromThread(); | |
| 493 const Closure verification_task = | |
| 494 Bind(&ExpectCalledOnValidThread, Unretained(&thread_checker)); | |
| 495 | |
| 496 constexpr size_t kNumRepetitions = 5; | |
| 497 for (size_t i = 0; i < kNumRepetitions; ++i) { | |
| 498 single_threaded_pool.pool()->PostTask(FROM_HERE, verification_task); | |
| 499 single_threaded_pool.pool() | |
| 500 ->GetTaskRunnerWithShutdownBehavior(SequencedWorkerPool::BLOCK_SHUTDOWN) | |
| 501 ->PostTask(FROM_HERE, verification_task); | |
| 502 single_threaded_pool.pool() | |
| 503 ->GetSequencedTaskRunner(SequencedWorkerPool::GetSequenceToken()) | |
| 504 ->PostTask(FROM_HERE, verification_task); | |
| 505 } | |
| 506 | |
| 507 // Wait for all verification tasks to run. | |
| 508 single_threaded_pool.pool()->Shutdown(); | |
|
danakj
2016/09/01 23:16:34
so i noticed that earlier test did ResetPool() ins
| |
| 509 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 510 TaskScheduler::GetInstance()->Shutdown(); | |
| 511 } | |
| 512 | |
| 436 // Test that tasks with the same sequence token are executed in order but don't | 513 // Test that tasks with the same sequence token are executed in order but don't |
| 437 // affect other tasks. | 514 // affect other tasks. |
| 438 TEST_F(SequencedWorkerPoolTest, Sequence) { | 515 TEST_P(SequencedWorkerPoolTest, Sequence) { |
| 439 // Fill all the worker threads except one. | 516 // Fill all the worker threads except one. |
| 440 const size_t kNumBackgroundTasks = kNumWorkerThreads - 1; | 517 const size_t kNumBackgroundTasks = kNumWorkerThreads - 1; |
| 441 ThreadBlocker background_blocker; | 518 ThreadBlocker background_blocker; |
| 442 for (size_t i = 0; i < kNumBackgroundTasks; i++) { | 519 for (size_t i = 0; i < kNumBackgroundTasks; i++) { |
| 443 pool()->PostWorkerTask(FROM_HERE, | 520 pool()->PostWorkerTask(FROM_HERE, |
| 444 base::Bind(&TestTracker::BlockTask, | 521 base::Bind(&TestTracker::BlockTask, |
| 445 tracker(), i, &background_blocker)); | 522 tracker(), i, &background_blocker)); |
| 446 } | 523 } |
| 447 tracker()->WaitUntilTasksBlocked(kNumBackgroundTasks); | 524 tracker()->WaitUntilTasksBlocked(kNumBackgroundTasks); |
| 448 | 525 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 489 // Allow the first task of token1 to complete. This should run the second. | 566 // Allow the first task of token1 to complete. This should run the second. |
| 490 blocker.Unblock(1); | 567 blocker.Unblock(1); |
| 491 result = tracker()->WaitUntilTasksComplete(kNumBackgroundTasks + 4); | 568 result = tracker()->WaitUntilTasksComplete(kNumBackgroundTasks + 4); |
| 492 ASSERT_EQ(kNumBackgroundTasks + 4, result.size()); | 569 ASSERT_EQ(kNumBackgroundTasks + 4, result.size()); |
| 493 EXPECT_EQ(100, result[result.size() - 2]); | 570 EXPECT_EQ(100, result[result.size() - 2]); |
| 494 EXPECT_EQ(101, result[result.size() - 1]); | 571 EXPECT_EQ(101, result[result.size() - 1]); |
| 495 } | 572 } |
| 496 | 573 |
| 497 // Tests that any tasks posted after Shutdown are ignored. | 574 // Tests that any tasks posted after Shutdown are ignored. |
| 498 // Disabled for flakiness. See http://crbug.com/166451. | 575 // Disabled for flakiness. See http://crbug.com/166451. |
| 499 TEST_F(SequencedWorkerPoolTest, DISABLED_IgnoresAfterShutdown) { | 576 TEST_P(SequencedWorkerPoolTest, DISABLED_IgnoresAfterShutdown) { |
| 500 // Start tasks to take all the threads and block them. | 577 // Start tasks to take all the threads and block them. |
| 501 EnsureAllWorkersCreated(); | 578 EnsureAllWorkersCreated(); |
| 502 ThreadBlocker blocker; | 579 ThreadBlocker blocker; |
| 503 for (size_t i = 0; i < kNumWorkerThreads; i++) { | 580 for (size_t i = 0; i < kNumWorkerThreads; i++) { |
| 504 pool()->PostWorkerTask(FROM_HERE, | 581 pool()->PostWorkerTask(FROM_HERE, |
| 505 base::Bind(&TestTracker::BlockTask, | 582 base::Bind(&TestTracker::BlockTask, |
| 506 tracker(), i, &blocker)); | 583 tracker(), i, &blocker)); |
| 507 } | 584 } |
| 508 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); | 585 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); |
| 509 | 586 |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 536 base::Bind(&TestTracker::FastTask, tracker(), 101), | 613 base::Bind(&TestTracker::FastTask, tracker(), 101), |
| 537 SequencedWorkerPool::SKIP_ON_SHUTDOWN)); | 614 SequencedWorkerPool::SKIP_ON_SHUTDOWN)); |
| 538 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior( | 615 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior( |
| 539 FROM_HERE, | 616 FROM_HERE, |
| 540 base::Bind(&TestTracker::FastTask, tracker(), 102), | 617 base::Bind(&TestTracker::FastTask, tracker(), 102), |
| 541 SequencedWorkerPool::BLOCK_SHUTDOWN)); | 618 SequencedWorkerPool::BLOCK_SHUTDOWN)); |
| 542 | 619 |
| 543 ASSERT_EQ(old_has_work_call_count, has_work_call_count()); | 620 ASSERT_EQ(old_has_work_call_count, has_work_call_count()); |
| 544 } | 621 } |
| 545 | 622 |
| 546 TEST_F(SequencedWorkerPoolTest, AllowsAfterShutdown) { | 623 TEST_P(SequencedWorkerPoolTest, AllowsAfterShutdown) { |
| 624 // TaskScheduler supports posting new BLOCK_SHUTDOWN tasks during shutdown | |
| 625 // (see TaskSchedulerTaskTrackerTest.WillPostAndRunDuringShutdown). However, | |
| 626 // since it doesn't provide a way to run a callback from inside its Shutdown() | |
| 627 // method, it would be hard to make this test work with redirection enabled. | |
| 628 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 629 return; | |
| 630 | |
| 547 // Test that <n> new blocking tasks are allowed provided they're posted | 631 // Test that <n> new blocking tasks are allowed provided they're posted |
| 548 // by a running tasks. | 632 // by a running tasks. |
| 549 EnsureAllWorkersCreated(); | 633 EnsureAllWorkersCreated(); |
| 550 ThreadBlocker blocker; | 634 ThreadBlocker blocker; |
| 551 | 635 |
| 552 // Start tasks to take all the threads and block them. | 636 // Start tasks to take all the threads and block them. |
| 553 const int kNumBlockTasks = static_cast<int>(kNumWorkerThreads); | 637 const int kNumBlockTasks = static_cast<int>(kNumWorkerThreads); |
| 554 for (int i = 0; i < kNumBlockTasks; ++i) { | 638 for (int i = 0; i < kNumBlockTasks; ++i) { |
| 555 EXPECT_TRUE(pool()->PostWorkerTask( | 639 EXPECT_TRUE(pool()->PostWorkerTask( |
| 556 FROM_HERE, | 640 FROM_HERE, |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 582 // Ensure that the correct number of tasks actually got run. | 666 // Ensure that the correct number of tasks actually got run. |
| 583 tracker()->WaitUntilTasksComplete(static_cast<size_t>( | 667 tracker()->WaitUntilTasksComplete(static_cast<size_t>( |
| 584 kNumBlockTasks + kNumQueuedTasks + kNumNewBlockingTasksToAllow)); | 668 kNumBlockTasks + kNumQueuedTasks + kNumNewBlockingTasksToAllow)); |
| 585 | 669 |
| 586 // Clean up the task IDs we added and go home. | 670 // Clean up the task IDs we added and go home. |
| 587 tracker()->ClearCompleteSequence(); | 671 tracker()->ClearCompleteSequence(); |
| 588 } | 672 } |
| 589 | 673 |
| 590 // Tests that blocking tasks can still be posted during shutdown, as long as | 674 // Tests that blocking tasks can still be posted during shutdown, as long as |
| 591 // the task is not being posted within the context of a running task. | 675 // the task is not being posted within the context of a running task. |
| 592 TEST_F(SequencedWorkerPoolTest, | 676 TEST_P(SequencedWorkerPoolTest, |
| 593 AllowsBlockingTasksDuringShutdownOutsideOfRunningTask) { | 677 AllowsBlockingTasksDuringShutdownOutsideOfRunningTask) { |
| 678 // TaskScheduler supports posting new BLOCK_SHUTDOWN tasks during shutdown | |
| 679 // (see TaskSchedulerTaskTrackerTest.WillPostAndRunDuringShutdown). However, | |
| 680 // since it doesn't provide a way to run a callback from inside its Shutdown() | |
| 681 // method, it would be hard to make this test work with redirection enabled. | |
| 682 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 683 return; | |
| 684 | |
| 594 EnsureAllWorkersCreated(); | 685 EnsureAllWorkersCreated(); |
| 595 ThreadBlocker blocker; | 686 ThreadBlocker blocker; |
| 596 | 687 |
| 597 // Start tasks to take all the threads and block them. | 688 // Start tasks to take all the threads and block them. |
| 598 const int kNumBlockTasks = static_cast<int>(kNumWorkerThreads); | 689 const int kNumBlockTasks = static_cast<int>(kNumWorkerThreads); |
| 599 for (int i = 0; i < kNumBlockTasks; ++i) { | 690 for (int i = 0; i < kNumBlockTasks; ++i) { |
| 600 EXPECT_TRUE(pool()->PostWorkerTask( | 691 EXPECT_TRUE(pool()->PostWorkerTask( |
| 601 FROM_HERE, | 692 FROM_HERE, |
| 602 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker))); | 693 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker))); |
| 603 } | 694 } |
| 604 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); | 695 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); |
| 605 | 696 |
| 606 // Setup to open the floodgates from within Shutdown(). | 697 // Setup to open the floodgates from within Shutdown(). |
| 607 SetWillWaitForShutdownCallback( | 698 SetWillWaitForShutdownCallback( |
| 608 base::Bind(&TestTracker::PostBlockingTaskThenUnblockThreads, | 699 base::Bind(&TestTracker::PostBlockingTaskThenUnblockThreads, |
| 609 scoped_refptr<TestTracker>(tracker()), pool(), &blocker, | 700 scoped_refptr<TestTracker>(tracker()), pool(), &blocker, |
| 610 kNumWorkerThreads)); | 701 kNumWorkerThreads)); |
| 611 pool()->Shutdown(kNumWorkerThreads + 1); | 702 pool()->Shutdown(kNumWorkerThreads + 1); |
| 612 | 703 |
| 613 // Ensure that the correct number of tasks actually got run. | 704 // Ensure that the correct number of tasks actually got run. |
| 614 tracker()->WaitUntilTasksComplete(static_cast<size_t>(kNumWorkerThreads + 1)); | 705 tracker()->WaitUntilTasksComplete(static_cast<size_t>(kNumWorkerThreads + 1)); |
| 615 tracker()->ClearCompleteSequence(); | 706 tracker()->ClearCompleteSequence(); |
| 616 } | 707 } |
| 617 | 708 |
| 618 // Tests that unrun tasks are discarded properly according to their shutdown | 709 // Tests that unrun tasks are discarded properly according to their shutdown |
| 619 // mode. | 710 // mode. |
| 620 TEST_F(SequencedWorkerPoolTest, DiscardOnShutdown) { | 711 TEST_P(SequencedWorkerPoolTest, DiscardOnShutdown) { |
| 712 // Since TaskScheduler doesn't provide a way to run a callback from inside its | |
| 713 // Shutdown() method, it would be hard to make this test work with redirection | |
| 714 // enabled. | |
| 715 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 716 return; | |
| 717 | |
| 621 // Start tasks to take all the threads and block them. | 718 // Start tasks to take all the threads and block them. |
| 622 EnsureAllWorkersCreated(); | 719 EnsureAllWorkersCreated(); |
| 623 ThreadBlocker blocker; | 720 ThreadBlocker blocker; |
| 624 for (size_t i = 0; i < kNumWorkerThreads; i++) { | 721 for (size_t i = 0; i < kNumWorkerThreads; i++) { |
| 625 pool()->PostWorkerTask(FROM_HERE, | 722 pool()->PostWorkerTask(FROM_HERE, |
| 626 base::Bind(&TestTracker::BlockTask, | 723 base::Bind(&TestTracker::BlockTask, |
| 627 tracker(), i, &blocker)); | 724 tracker(), i, &blocker)); |
| 628 } | 725 } |
| 629 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); | 726 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); |
| 630 | 727 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 654 | 751 |
| 655 // The kNumWorkerThread items should have completed, plus the BLOCK_SHUTDOWN | 752 // The kNumWorkerThread items should have completed, plus the BLOCK_SHUTDOWN |
| 656 // one, in no particular order. | 753 // one, in no particular order. |
| 657 ASSERT_EQ(kNumWorkerThreads + 1, result.size()); | 754 ASSERT_EQ(kNumWorkerThreads + 1, result.size()); |
| 658 for (size_t i = 0; i < kNumWorkerThreads; i++) | 755 for (size_t i = 0; i < kNumWorkerThreads; i++) |
| 659 EXPECT_TRUE(ContainsValue(result, static_cast<int>(i))); | 756 EXPECT_TRUE(ContainsValue(result, static_cast<int>(i))); |
| 660 EXPECT_TRUE(ContainsValue(result, 102)); | 757 EXPECT_TRUE(ContainsValue(result, 102)); |
| 661 } | 758 } |
| 662 | 759 |
| 663 // Tests that CONTINUE_ON_SHUTDOWN tasks don't block shutdown. | 760 // Tests that CONTINUE_ON_SHUTDOWN tasks don't block shutdown. |
| 664 TEST_F(SequencedWorkerPoolTest, ContinueOnShutdown) { | 761 TEST_P(SequencedWorkerPoolTest, ContinueOnShutdown) { |
| 665 scoped_refptr<TaskRunner> runner(pool()->GetTaskRunnerWithShutdownBehavior( | 762 scoped_refptr<TaskRunner> runner(pool()->GetTaskRunnerWithShutdownBehavior( |
| 666 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); | 763 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); |
| 667 scoped_refptr<SequencedTaskRunner> sequenced_runner( | 764 scoped_refptr<SequencedTaskRunner> sequenced_runner( |
| 668 pool()->GetSequencedTaskRunnerWithShutdownBehavior( | 765 pool()->GetSequencedTaskRunnerWithShutdownBehavior( |
| 669 pool()->GetSequenceToken(), | 766 pool()->GetSequenceToken(), |
| 670 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); | 767 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); |
| 671 EnsureAllWorkersCreated(); | 768 EnsureAllWorkersCreated(); |
| 672 ThreadBlocker blocker; | 769 ThreadBlocker blocker; |
| 673 pool()->PostWorkerTaskWithShutdownBehavior( | 770 pool()->PostWorkerTaskWithShutdownBehavior( |
| 674 FROM_HERE, | 771 FROM_HERE, |
| 675 base::Bind(&TestTracker::BlockTask, | 772 base::Bind(&TestTracker::BlockTask, |
| 676 tracker(), 0, &blocker), | 773 tracker(), 0, &blocker), |
| 677 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); | 774 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); |
| 678 runner->PostTask( | 775 runner->PostTask( |
| 679 FROM_HERE, | 776 FROM_HERE, |
| 680 base::Bind(&TestTracker::BlockTask, | 777 base::Bind(&TestTracker::BlockTask, |
| 681 tracker(), 1, &blocker)); | 778 tracker(), 1, &blocker)); |
| 682 sequenced_runner->PostTask( | 779 sequenced_runner->PostTask( |
| 683 FROM_HERE, | 780 FROM_HERE, |
| 684 base::Bind(&TestTracker::BlockTask, | 781 base::Bind(&TestTracker::BlockTask, |
| 685 tracker(), 2, &blocker)); | 782 tracker(), 2, &blocker)); |
| 686 | 783 |
| 687 tracker()->WaitUntilTasksBlocked(3); | 784 tracker()->WaitUntilTasksBlocked(3); |
| 688 | 785 |
| 689 // This should not block. If this test hangs, it means it failed. | 786 // Shutting down the pool should not be blocked by CONTINUE_ON_SHUTDOWN tasks. |
| 787 // If this test hangs, it means it failed. | |
| 788 // Note: This is a no-op when redirection to the TaskScheduler is enabled. | |
| 690 pool()->Shutdown(); | 789 pool()->Shutdown(); |
| 691 | 790 |
| 791 // Shutting down the TaskScheduler should not be blocked by | |
| 792 // CONTINUE_ON_SHUTDOWN tasks. | |
| 793 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 794 TaskScheduler::GetInstance()->Shutdown(); | |
| 795 | |
| 692 // The task should not have completed yet. | 796 // The task should not have completed yet. |
| 693 EXPECT_EQ(0u, tracker()->WaitUntilTasksComplete(0).size()); | 797 EXPECT_EQ(0u, tracker()->WaitUntilTasksComplete(0).size()); |
| 694 | 798 |
| 695 // Posting more tasks should fail. | 799 // Posting more tasks should fail. |
| 696 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior( | 800 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior( |
| 697 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0), | 801 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0), |
| 698 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); | 802 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); |
| 699 EXPECT_FALSE(runner->PostTask( | 803 EXPECT_FALSE(runner->PostTask( |
| 700 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0))); | 804 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0))); |
| 701 EXPECT_FALSE(sequenced_runner->PostTask( | 805 EXPECT_FALSE(sequenced_runner->PostTask( |
| 702 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0))); | 806 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0))); |
| 703 | 807 |
| 704 // Continue the background thread and make sure the tasks can complete. | 808 // Continue the background thread and make sure the tasks can complete. |
| 705 blocker.Unblock(3); | 809 blocker.Unblock(3); |
| 706 std::vector<int> result = tracker()->WaitUntilTasksComplete(3); | 810 std::vector<int> result = tracker()->WaitUntilTasksComplete(3); |
| 707 EXPECT_EQ(3u, result.size()); | 811 EXPECT_EQ(3u, result.size()); |
| 708 } | 812 } |
| 709 | 813 |
| 710 // Tests that SKIP_ON_SHUTDOWN tasks that have been started block Shutdown | 814 // Tests that SKIP_ON_SHUTDOWN tasks that have been started block Shutdown |
| 711 // until they stop, but tasks not yet started do not. | 815 // until they stop, but tasks not yet started do not. |
| 712 TEST_F(SequencedWorkerPoolTest, SkipOnShutdown) { | 816 TEST_P(SequencedWorkerPoolTest, SkipOnShutdown) { |
| 817 // Since TaskScheduler doesn't provide a way to run a callback from inside its | |
| 818 // Shutdown() method, it would be hard to make this test work with redirection | |
| 819 // enabled. | |
|
danakj
2016/09/01 23:16:34
For each of these tests that are being skipped. Ca
| |
| 820 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 821 return; | |
| 822 | |
| 713 // Start tasks to take all the threads and block them. | 823 // Start tasks to take all the threads and block them. |
| 714 EnsureAllWorkersCreated(); | 824 EnsureAllWorkersCreated(); |
| 715 ThreadBlocker blocker; | 825 ThreadBlocker blocker; |
| 716 | 826 |
| 717 // Now block all the threads with SKIP_ON_SHUTDOWN. Shutdown() should not | 827 // Now block all the threads with SKIP_ON_SHUTDOWN. Shutdown() should not |
| 718 // return until these tasks have completed. | 828 // return until these tasks have completed. |
| 719 for (size_t i = 0; i < kNumWorkerThreads; i++) { | 829 for (size_t i = 0; i < kNumWorkerThreads; i++) { |
| 720 pool()->PostWorkerTaskWithShutdownBehavior( | 830 pool()->PostWorkerTaskWithShutdownBehavior( |
| 721 FROM_HERE, | 831 FROM_HERE, |
| 722 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker), | 832 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker), |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 753 // allowed to complete. No additional non-blocking tasks should have been | 863 // allowed to complete. No additional non-blocking tasks should have been |
| 754 // started. | 864 // started. |
| 755 ASSERT_EQ(kNumWorkerThreads, result.size()); | 865 ASSERT_EQ(kNumWorkerThreads, result.size()); |
| 756 for (size_t i = 0; i < kNumWorkerThreads; i++) | 866 for (size_t i = 0; i < kNumWorkerThreads; i++) |
| 757 EXPECT_TRUE(ContainsValue(result, static_cast<int>(i))); | 867 EXPECT_TRUE(ContainsValue(result, static_cast<int>(i))); |
| 758 } | 868 } |
| 759 | 869 |
| 760 // Ensure all worker threads are created, and then trigger a spurious | 870 // Ensure all worker threads are created, and then trigger a spurious |
| 761 // work signal. This shouldn't cause any other work signals to be | 871 // work signal. This shouldn't cause any other work signals to be |
| 762 // triggered. This is a regression test for http://crbug.com/117469. | 872 // triggered. This is a regression test for http://crbug.com/117469. |
| 763 TEST_F(SequencedWorkerPoolTest, SpuriousWorkSignal) { | 873 TEST_P(SequencedWorkerPoolTest, SpuriousWorkSignal) { |
| 874 // This test doesn't apply when tasks are redirected to the TaskScheduler. | |
| 875 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 876 return; | |
| 877 | |
| 764 EnsureAllWorkersCreated(); | 878 EnsureAllWorkersCreated(); |
| 765 int old_has_work_call_count = has_work_call_count(); | 879 int old_has_work_call_count = has_work_call_count(); |
| 766 pool()->SignalHasWorkForTesting(); | 880 pool()->SignalHasWorkForTesting(); |
| 767 // This is inherently racy, but can only produce false positives. | 881 // This is inherently racy, but can only produce false positives. |
| 768 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); | 882 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); |
| 769 EXPECT_EQ(old_has_work_call_count + 1, has_work_call_count()); | 883 EXPECT_EQ(old_has_work_call_count + 1, has_work_call_count()); |
| 770 } | 884 } |
| 771 | 885 |
| 772 void IsRunningOnCurrentThreadTask( | 886 void IsRunningOnCurrentThreadTask( |
| 773 SequencedWorkerPool::SequenceToken test_positive_token, | 887 SequencedWorkerPool::SequenceToken test_positive_token, |
| 774 SequencedWorkerPool::SequenceToken test_negative_token, | 888 SequencedWorkerPool::SequenceToken test_negative_token, |
| 775 SequencedWorkerPool* pool, | 889 SequencedWorkerPool* pool, |
| 776 SequencedWorkerPool* unused_pool) { | 890 SequencedWorkerPool* unused_pool, |
| 891 SequencedWorkerPoolRedirection redirection) { | |
| 777 EXPECT_TRUE(pool->RunsTasksOnCurrentThread()); | 892 EXPECT_TRUE(pool->RunsTasksOnCurrentThread()); |
| 778 EXPECT_TRUE(pool->IsRunningSequenceOnCurrentThread(test_positive_token)); | 893 EXPECT_TRUE(pool->IsRunningSequenceOnCurrentThread(test_positive_token)); |
| 779 EXPECT_FALSE(pool->IsRunningSequenceOnCurrentThread(test_negative_token)); | 894 |
| 780 EXPECT_FALSE(unused_pool->RunsTasksOnCurrentThread()); | 895 if (redirection == SequencedWorkerPoolRedirection::NONE) { |
| 781 EXPECT_FALSE( | 896 // Tasks posted to different pools may run on the same threads when |
| 782 unused_pool->IsRunningSequenceOnCurrentThread(test_positive_token)); | 897 // redirection to the TaskScheduler is enabled. |
| 783 EXPECT_FALSE( | 898 EXPECT_FALSE(unused_pool->RunsTasksOnCurrentThread()); |
| 784 unused_pool->IsRunningSequenceOnCurrentThread(test_negative_token)); | 899 |
| 900 // TODO(gab): When redirection to the TaskScheduler is enabled, | |
| 901 // IsRunningSequenceOnCurrentThread() returns true if a task bound to the | |
| 902 // provided sequence token *could* run on the current thread. Once the | |
| 903 // method is fixed to return true only when called from a thread that is | |
| 904 // *currently running* a task bound to the provided sequence token, move | |
| 905 // these tests out of the conditional. | |
|
danakj
2016/09/01 23:16:34
Is there a bug to point at?
| |
| 906 EXPECT_FALSE(pool->IsRunningSequenceOnCurrentThread(test_negative_token)); | |
| 907 EXPECT_FALSE( | |
| 908 unused_pool->IsRunningSequenceOnCurrentThread(test_positive_token)); | |
| 909 EXPECT_FALSE( | |
| 910 unused_pool->IsRunningSequenceOnCurrentThread(test_negative_token)); | |
| 911 } | |
| 785 } | 912 } |
| 786 | 913 |
| 787 // Verify correctness of the IsRunningSequenceOnCurrentThread method. | 914 // Verify correctness of the IsRunningSequenceOnCurrentThread method. |
| 788 TEST_F(SequencedWorkerPoolTest, IsRunningOnCurrentThread) { | 915 TEST_P(SequencedWorkerPoolTest, IsRunningOnCurrentThread) { |
| 789 SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken(); | 916 SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken(); |
| 790 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken(); | 917 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken(); |
| 791 SequencedWorkerPool::SequenceToken unsequenced_token; | 918 SequencedWorkerPool::SequenceToken unsequenced_token; |
| 792 | 919 |
| 793 SequencedWorkerPoolOwner unused_pool_owner(2, "unused_pool"); | 920 SequencedWorkerPoolOwner unused_pool_owner(2, "unused_pool"); |
| 794 | 921 |
| 795 EXPECT_FALSE(pool()->RunsTasksOnCurrentThread()); | 922 EXPECT_FALSE(pool()->RunsTasksOnCurrentThread()); |
| 796 EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(token1)); | 923 EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(token1)); |
| 797 EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(token2)); | 924 EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(token2)); |
| 798 EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(unsequenced_token)); | 925 EXPECT_FALSE(pool()->IsRunningSequenceOnCurrentThread(unsequenced_token)); |
| 799 EXPECT_FALSE(unused_pool_owner.pool()->RunsTasksOnCurrentThread()); | 926 EXPECT_FALSE(unused_pool_owner.pool()->RunsTasksOnCurrentThread()); |
| 800 EXPECT_FALSE( | 927 EXPECT_FALSE( |
| 801 unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread(token1)); | 928 unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread(token1)); |
| 802 EXPECT_FALSE( | 929 EXPECT_FALSE( |
| 803 unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread(token2)); | 930 unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread(token2)); |
| 804 EXPECT_FALSE(unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread( | 931 EXPECT_FALSE(unused_pool_owner.pool()->IsRunningSequenceOnCurrentThread( |
| 805 unsequenced_token)); | 932 unsequenced_token)); |
| 806 | 933 |
| 807 pool()->PostSequencedWorkerTask( | 934 pool()->PostSequencedWorkerTask( |
| 808 token1, FROM_HERE, | 935 token1, FROM_HERE, |
| 809 base::Bind(&IsRunningOnCurrentThreadTask, token1, token2, | 936 base::Bind(&IsRunningOnCurrentThreadTask, token1, token2, |
| 810 base::RetainedRef(pool()), | 937 base::RetainedRef(pool()), |
| 811 base::RetainedRef(unused_pool_owner.pool()))); | 938 base::RetainedRef(unused_pool_owner.pool()), GetParam())); |
| 812 pool()->PostSequencedWorkerTask( | 939 pool()->PostSequencedWorkerTask( |
| 813 token2, FROM_HERE, | 940 token2, FROM_HERE, |
| 814 base::Bind(&IsRunningOnCurrentThreadTask, token2, unsequenced_token, | 941 base::Bind(&IsRunningOnCurrentThreadTask, token2, unsequenced_token, |
| 815 base::RetainedRef(pool()), | 942 base::RetainedRef(pool()), |
| 816 base::RetainedRef(unused_pool_owner.pool()))); | 943 base::RetainedRef(unused_pool_owner.pool()), GetParam())); |
| 817 pool()->PostWorkerTask( | 944 pool()->PostWorkerTask( |
| 818 FROM_HERE, base::Bind(&IsRunningOnCurrentThreadTask, unsequenced_token, | 945 FROM_HERE, |
| 819 token1, base::RetainedRef(pool()), | 946 base::Bind(&IsRunningOnCurrentThreadTask, unsequenced_token, token1, |
| 820 base::RetainedRef(unused_pool_owner.pool()))); | 947 base::RetainedRef(pool()), |
| 948 base::RetainedRef(unused_pool_owner.pool()), GetParam())); | |
| 821 } | 949 } |
| 822 | 950 |
| 823 // Checks that tasks are destroyed in the right context during shutdown. If a | 951 // Checks that tasks are destroyed in the right context during shutdown. If a |
| 824 // task is destroyed while SequencedWorkerPool's global lock is held, | 952 // task is destroyed while SequencedWorkerPool's global lock is held, |
| 825 // SequencedWorkerPool might deadlock. | 953 // SequencedWorkerPool might deadlock. |
| 826 TEST_F(SequencedWorkerPoolTest, AvoidsDeadlockOnShutdown) { | 954 TEST_P(SequencedWorkerPoolTest, AvoidsDeadlockOnShutdown) { |
| 955 // Since the TaskScheduler doesn't delete pending tasks on shutdown, this test | |
| 956 // doesn't apply when tasks are redirected to the TaskScheduler. | |
| 957 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 958 return; | |
| 959 | |
| 827 for (int i = 0; i < 4; ++i) { | 960 for (int i = 0; i < 4; ++i) { |
| 828 scoped_refptr<DestructionDeadlockChecker> checker( | 961 scoped_refptr<DestructionDeadlockChecker> checker( |
| 829 new DestructionDeadlockChecker(pool())); | 962 new DestructionDeadlockChecker(pool())); |
| 830 tracker()->PostRepostingTask(pool(), checker); | 963 tracker()->PostRepostingTask(pool(), checker); |
| 831 } | 964 } |
| 832 | 965 |
| 833 // Shutting down the pool should destroy the DestructionDeadlockCheckers, | 966 // Shutting down the pool should destroy the DestructionDeadlockCheckers, |
| 834 // which in turn should not deadlock in their destructors. | 967 // which in turn should not deadlock in their destructors. |
| 835 pool()->Shutdown(); | 968 pool()->Shutdown(); |
| 836 } | 969 } |
| 837 | 970 |
| 838 // Similar to the test AvoidsDeadlockOnShutdown, but there are now also | 971 // Similar to the test AvoidsDeadlockOnShutdown, but there are now also |
| 839 // sequenced, blocking tasks in the queue during shutdown. | 972 // sequenced, blocking tasks in the queue during shutdown. |
| 840 TEST_F(SequencedWorkerPoolTest, | 973 TEST_P(SequencedWorkerPoolTest, |
| 841 AvoidsDeadlockOnShutdownWithSequencedBlockingTasks) { | 974 AvoidsDeadlockOnShutdownWithSequencedBlockingTasks) { |
| 975 // Since the TaskScheduler doesn't delete pending tasks on shutdown, this test | |
| 976 // doesn't apply when tasks are redirected to the TaskScheduler. | |
| 977 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 978 return; | |
| 979 | |
| 842 const std::string sequence_token_name("name"); | 980 const std::string sequence_token_name("name"); |
| 843 for (int i = 0; i < 4; ++i) { | 981 for (int i = 0; i < 4; ++i) { |
| 844 scoped_refptr<DestructionDeadlockChecker> checker( | 982 scoped_refptr<DestructionDeadlockChecker> checker( |
| 845 new DestructionDeadlockChecker(pool())); | 983 new DestructionDeadlockChecker(pool())); |
| 846 tracker()->PostRepostingTask(pool(), checker); | 984 tracker()->PostRepostingTask(pool(), checker); |
| 847 | 985 |
| 848 SequencedWorkerPool::SequenceToken token1 = | 986 SequencedWorkerPool::SequenceToken token1 = |
| 849 pool()->GetNamedSequenceToken(sequence_token_name); | 987 pool()->GetNamedSequenceToken(sequence_token_name); |
| 850 tracker()->PostRepostingBlockingTask(pool(), token1); | 988 tracker()->PostRepostingBlockingTask(pool(), token1); |
| 851 } | 989 } |
| 852 | 990 |
| 853 // Shutting down the pool should destroy the DestructionDeadlockCheckers, | 991 // Shutting down the pool should destroy the DestructionDeadlockCheckers, |
| 854 // which in turn should not deadlock in their destructors. | 992 // which in turn should not deadlock in their destructors. |
| 855 pool()->Shutdown(); | 993 pool()->Shutdown(); |
| 856 } | 994 } |
| 857 | 995 |
| 858 // Verify that FlushForTesting works as intended. | 996 // Verify that FlushForTesting works as intended. |
| 859 TEST_F(SequencedWorkerPoolTest, FlushForTesting) { | 997 TEST_P(SequencedWorkerPoolTest, FlushForTesting) { |
| 998 // FlushForTesting cannot be called when tasks are redirected to the | |
| 999 // TaskScheduler. | |
| 1000 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 1001 return; | |
| 1002 | |
| 860 // Should be fine to call on a new instance. | 1003 // Should be fine to call on a new instance. |
| 861 pool()->FlushForTesting(); | 1004 pool()->FlushForTesting(); |
| 862 | 1005 |
| 863 // Queue up a bunch of work, including a long delayed task and | 1006 // Queue up a bunch of work, including a long delayed task and |
| 864 // a task that produces additional tasks as an artifact. | 1007 // a task that produces additional tasks as an artifact. |
| 865 pool()->PostDelayedWorkerTask( | 1008 pool()->PostDelayedWorkerTask( |
| 866 FROM_HERE, | 1009 FROM_HERE, |
| 867 base::Bind(&TestTracker::FastTask, tracker(), 0), | 1010 base::Bind(&TestTracker::FastTask, tracker(), 0), |
| 868 TimeDelta::FromMinutes(5)); | 1011 TimeDelta::FromMinutes(5)); |
| 869 pool()->PostWorkerTask(FROM_HERE, | 1012 pool()->PostWorkerTask(FROM_HERE, |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 888 // Should be fine to call on an idle instance with all threads created, and | 1031 // Should be fine to call on an idle instance with all threads created, and |
| 889 // spamming the method shouldn't deadlock or confuse the class. | 1032 // spamming the method shouldn't deadlock or confuse the class. |
| 890 pool()->FlushForTesting(); | 1033 pool()->FlushForTesting(); |
| 891 pool()->FlushForTesting(); | 1034 pool()->FlushForTesting(); |
| 892 | 1035 |
| 893 // Should be fine to call after shutdown too. | 1036 // Should be fine to call after shutdown too. |
| 894 pool()->Shutdown(); | 1037 pool()->Shutdown(); |
| 895 pool()->FlushForTesting(); | 1038 pool()->FlushForTesting(); |
| 896 } | 1039 } |
| 897 | 1040 |
| 1041 INSTANTIATE_TEST_CASE_P( | |
| 1042 NoRedirection, | |
| 1043 SequencedWorkerPoolTest, | |
| 1044 ::testing::Values(SequencedWorkerPoolRedirection::NONE)); | |
| 1045 INSTANTIATE_TEST_CASE_P( | |
| 1046 RedirectionToTaskScheduler, | |
| 1047 SequencedWorkerPoolTest, | |
| 1048 ::testing::Values(SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)); | |
| 1049 | |
| 898 namespace { | 1050 namespace { |
| 899 | 1051 |
| 900 void CheckWorkerPoolAndSequenceToken( | 1052 void CheckWorkerPoolAndSequenceToken( |
| 901 const scoped_refptr<SequencedWorkerPool>& expected_pool, | 1053 const scoped_refptr<SequencedWorkerPool>& expected_pool, |
| 902 SequencedWorkerPool::SequenceToken expected_token) { | 1054 SequencedWorkerPool::SequenceToken expected_token) { |
| 903 SequencedWorkerPool::SequenceToken token = | 1055 SequencedWorkerPool::SequenceToken token = |
| 904 SequencedWorkerPool::GetSequenceTokenForCurrentThread(); | 1056 SequencedWorkerPool::GetSequenceTokenForCurrentThread(); |
| 905 EXPECT_EQ(expected_token.ToString(), token.ToString()); | 1057 EXPECT_EQ(expected_token.ToString(), token.ToString()); |
| 906 | 1058 |
| 907 scoped_refptr<SequencedWorkerPool> pool = | 1059 scoped_refptr<SequencedWorkerPool> pool = |
| 908 SequencedWorkerPool::GetWorkerPoolForCurrentThread(); | 1060 SequencedWorkerPool::GetWorkerPoolForCurrentThread(); |
| 909 EXPECT_EQ(expected_pool, pool); | 1061 EXPECT_EQ(expected_pool, pool); |
| 910 } | 1062 } |
| 911 | 1063 |
| 912 } // namespace | 1064 } // namespace |
| 913 | 1065 |
| 914 TEST_F(SequencedWorkerPoolTest, GetWorkerPoolAndSequenceTokenForCurrentThread) { | 1066 TEST_P(SequencedWorkerPoolTest, GetWorkerPoolAndSequenceTokenForCurrentThread) { |
| 1067 // SequencedWorkerPool::GetSequenceTokenForCurrentThread() isn't supported | |
| 1068 // when tasks are redirected to the TaskScheduler. It will never be supported | |
| 1069 // since its only uses are in SequencedTaskRunnerHandle and | |
| 1070 // SequenceCheckerImpl which don't need it when redirection is enabled. | |
| 1071 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 1072 return; | |
| 1073 | |
| 915 EnsureAllWorkersCreated(); | 1074 EnsureAllWorkersCreated(); |
| 916 | 1075 |
| 917 // The current thread should have neither a worker pool nor a sequence token. | 1076 // The current thread should have neither a worker pool nor a sequence token. |
| 918 SequencedWorkerPool::SequenceToken local_token = | 1077 SequencedWorkerPool::SequenceToken local_token = |
| 919 SequencedWorkerPool::GetSequenceTokenForCurrentThread(); | 1078 SequencedWorkerPool::GetSequenceTokenForCurrentThread(); |
| 920 scoped_refptr<SequencedWorkerPool> local_pool = | 1079 scoped_refptr<SequencedWorkerPool> local_pool = |
| 921 SequencedWorkerPool::GetWorkerPoolForCurrentThread(); | 1080 SequencedWorkerPool::GetWorkerPoolForCurrentThread(); |
| 922 EXPECT_FALSE(local_token.IsValid()) << local_token.ToString(); | 1081 EXPECT_FALSE(local_token.IsValid()) << local_token.ToString(); |
| 923 EXPECT_FALSE(local_pool); | 1082 EXPECT_FALSE(local_pool); |
| 924 | 1083 |
| 925 SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken(); | 1084 SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken(); |
| 926 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken(); | 1085 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken(); |
| 927 pool()->PostSequencedWorkerTask( | 1086 pool()->PostSequencedWorkerTask( |
| 928 token1, FROM_HERE, | 1087 token1, FROM_HERE, |
| 929 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token1)); | 1088 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token1)); |
| 930 pool()->PostSequencedWorkerTask( | 1089 pool()->PostSequencedWorkerTask( |
| 931 token2, FROM_HERE, | 1090 token2, FROM_HERE, |
| 932 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token2)); | 1091 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token2)); |
| 933 | 1092 |
| 934 pool()->PostWorkerTask(FROM_HERE, | 1093 pool()->PostWorkerTask(FROM_HERE, |
| 935 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), | 1094 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), |
| 936 SequencedWorkerPool::SequenceToken())); | 1095 SequencedWorkerPool::SequenceToken())); |
| 937 | 1096 |
| 938 pool()->FlushForTesting(); | 1097 pool()->FlushForTesting(); |
| 939 } | 1098 } |
| 940 | 1099 |
| 941 TEST_F(SequencedWorkerPoolTest, ShutsDownCleanWithContinueOnShutdown) { | 1100 template <SequencedWorkerPoolRedirection redirection> |
| 942 scoped_refptr<SequencedTaskRunner> task_runner = | |
| 943 pool()->GetSequencedTaskRunnerWithShutdownBehavior( | |
| 944 pool()->GetSequenceToken(), | |
| 945 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); | |
| 946 | |
| 947 // Upon test exit, should shut down without hanging. | |
| 948 pool()->Shutdown(); | |
| 949 } | |
| 950 | |
| 951 class SequencedWorkerPoolTaskRunnerTestDelegate { | 1101 class SequencedWorkerPoolTaskRunnerTestDelegate { |
| 952 public: | 1102 public: |
| 953 SequencedWorkerPoolTaskRunnerTestDelegate() {} | 1103 SequencedWorkerPoolTaskRunnerTestDelegate() {} |
| 954 | 1104 |
| 955 ~SequencedWorkerPoolTaskRunnerTestDelegate() {} | 1105 ~SequencedWorkerPoolTaskRunnerTestDelegate() {} |
| 956 | 1106 |
| 957 void StartTaskRunner() { | 1107 void StartTaskRunner() { |
| 958 pool_owner_.reset( | 1108 pool_owner_.reset(new SequencedWorkerPoolOwner( |
| 959 new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest")); | 1109 kNumWorkerThreads, "SequencedWorkerPoolTaskRunnerTest")); |
| 1110 | |
| 1111 if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 1112 StartRedirectionToTaskScheduler(kNumWorkerThreads); | |
| 960 } | 1113 } |
| 961 | 1114 |
| 962 scoped_refptr<SequencedWorkerPool> GetTaskRunner() { | 1115 scoped_refptr<SequencedWorkerPool> GetTaskRunner() { |
| 963 return pool_owner_->pool(); | 1116 return pool_owner_->pool(); |
| 964 } | 1117 } |
| 965 | 1118 |
| 966 void StopTaskRunner() { | 1119 void StopTaskRunner() { |
| 967 // Make sure all tasks are run before shutting down. Delayed tasks are | 1120 pool_owner_->pool()->Shutdown(kNumAllowedBlockShutdownTasks); |
| 968 // not run, they're simply deleted. | 1121 if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) { |
| 969 pool_owner_->pool()->FlushForTesting(); | 1122 // When redirection to the TaskScheduler is enabled, shutting down the |
| 970 pool_owner_->pool()->Shutdown(); | 1123 // pool is a no-op. It is necessary to shut down the TaskScheduler to make |
| 971 // Don't reset |pool_owner_| here, as the test may still hold a | 1124 // sure that all tasks have been executed. |
| 972 // reference to the pool. | 1125 TaskScheduler::GetInstance()->Shutdown(); |
| 1126 StopRedirectionToTaskScheduler(); | |
| 1127 } | |
| 1128 // Don't reset |pool_owner_| here, as the test may still hold a reference to | |
| 1129 // the pool. | |
| 973 } | 1130 } |
| 974 | 1131 |
| 975 private: | 1132 private: |
| 976 MessageLoop message_loop_; | 1133 MessageLoop message_loop_; |
| 977 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_; | 1134 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_; |
| 978 }; | 1135 }; |
| 979 | 1136 |
| 1137 INSTANTIATE_TYPED_TEST_CASE_P(SequencedWorkerPool, | |
| 1138 TaskRunnerTest, | |
| 1139 SequencedWorkerPoolTaskRunnerTestDelegate< | |
| 1140 SequencedWorkerPoolRedirection::NONE>); | |
| 1141 INSTANTIATE_TYPED_TEST_CASE_P(SequencedWorkerPool, | |
| 1142 TaskRunnerAffinityTest, | |
| 1143 SequencedWorkerPoolTaskRunnerTestDelegate< | |
| 1144 SequencedWorkerPoolRedirection::NONE>); | |
| 980 INSTANTIATE_TYPED_TEST_CASE_P( | 1145 INSTANTIATE_TYPED_TEST_CASE_P( |
| 981 SequencedWorkerPool, TaskRunnerTest, | 1146 SequencedWorkerPoolToTaskScheduler, |
| 982 SequencedWorkerPoolTaskRunnerTestDelegate); | 1147 TaskRunnerTest, |
| 983 INSTANTIATE_TYPED_TEST_CASE_P(SequencedWorkerPool, TaskRunnerAffinityTest, | 1148 SequencedWorkerPoolTaskRunnerTestDelegate< |
| 984 SequencedWorkerPoolTaskRunnerTestDelegate); | 1149 SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER>); |
| 1150 INSTANTIATE_TYPED_TEST_CASE_P( | |
| 1151 SequencedWorkerPoolToTaskScheduler, | |
| 1152 TaskRunnerAffinityTest, | |
| 1153 SequencedWorkerPoolTaskRunnerTestDelegate< | |
| 1154 SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER>); | |
| 985 | 1155 |
| 1156 template <SequencedWorkerPoolRedirection redirection> | |
| 986 class SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate { | 1157 class SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate { |
| 987 public: | 1158 public: |
| 988 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate() {} | 1159 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate() {} |
| 989 | 1160 |
| 990 ~SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate() { | 1161 ~SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate() { |
| 991 } | 1162 } |
| 992 | 1163 |
| 993 void StartTaskRunner() { | 1164 void StartTaskRunner() { |
| 994 pool_owner_.reset( | 1165 pool_owner_.reset(new SequencedWorkerPoolOwner( |
| 995 new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest")); | 1166 kNumWorkerThreads, "SequencedWorkerPoolSequencedTaskRunnerTest")); |
| 996 task_runner_ = pool_owner_->pool()->GetTaskRunnerWithShutdownBehavior( | 1167 task_runner_ = pool_owner_->pool()->GetTaskRunnerWithShutdownBehavior( |
| 997 SequencedWorkerPool::BLOCK_SHUTDOWN); | 1168 SequencedWorkerPool::BLOCK_SHUTDOWN); |
| 1169 | |
| 1170 if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 1171 StartRedirectionToTaskScheduler(kNumWorkerThreads); | |
| 998 } | 1172 } |
| 999 | 1173 |
| 1000 scoped_refptr<TaskRunner> GetTaskRunner() { | 1174 scoped_refptr<TaskRunner> GetTaskRunner() { |
| 1001 return task_runner_; | 1175 return task_runner_; |
| 1002 } | 1176 } |
| 1003 | 1177 |
| 1004 void StopTaskRunner() { | 1178 void StopTaskRunner() { |
| 1005 // Make sure all tasks are run before shutting down. Delayed tasks are | 1179 pool_owner_->pool()->Shutdown(kNumAllowedBlockShutdownTasks); |
| 1006 // not run, they're simply deleted. | 1180 if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) { |
| 1007 pool_owner_->pool()->FlushForTesting(); | 1181 // When redirection to the TaskScheduler is enabled, shutting down the |
| 1008 pool_owner_->pool()->Shutdown(); | 1182 // pool is a no-op. It is necessary to shut down the TaskScheduler to make |
| 1009 // Don't reset |pool_owner_| here, as the test may still hold a | 1183 // sure that all tasks have been executed. |
| 1010 // reference to the pool. | 1184 TaskScheduler::GetInstance()->Shutdown(); |
| 1185 StopRedirectionToTaskScheduler(); | |
| 1186 } | |
| 1187 // Don't reset |pool_owner_| here, as the test may still hold a reference to | |
| 1188 // the pool. | |
| 1011 } | 1189 } |
| 1012 | 1190 |
| 1013 private: | 1191 private: |
| 1014 MessageLoop message_loop_; | 1192 MessageLoop message_loop_; |
| 1015 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_; | 1193 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_; |
| 1016 scoped_refptr<TaskRunner> task_runner_; | 1194 scoped_refptr<TaskRunner> task_runner_; |
| 1017 }; | 1195 }; |
| 1018 | 1196 |
| 1019 INSTANTIATE_TYPED_TEST_CASE_P( | 1197 INSTANTIATE_TYPED_TEST_CASE_P( |
| 1020 SequencedWorkerPoolTaskRunner, TaskRunnerTest, | 1198 SequencedWorkerPoolTaskRunner, |
| 1021 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate); | 1199 TaskRunnerTest, |
| 1200 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate< | |
| 1201 SequencedWorkerPoolRedirection::NONE>); | |
| 1022 INSTANTIATE_TYPED_TEST_CASE_P( | 1202 INSTANTIATE_TYPED_TEST_CASE_P( |
| 1023 SequencedWorkerPoolTaskRunner, TaskRunnerAffinityTest, | 1203 SequencedWorkerPoolTaskRunner, |
| 1024 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate); | 1204 TaskRunnerAffinityTest, |
| 1205 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate< | |
| 1206 SequencedWorkerPoolRedirection::NONE>); | |
| 1207 INSTANTIATE_TYPED_TEST_CASE_P( | |
| 1208 SequencedWorkerPoolTaskRunnerToTaskScheduler, | |
| 1209 TaskRunnerTest, | |
| 1210 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate< | |
| 1211 SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER>); | |
| 1212 INSTANTIATE_TYPED_TEST_CASE_P( | |
| 1213 SequencedWorkerPoolTaskRunnerToTaskScheduler, | |
| 1214 TaskRunnerAffinityTest, | |
| 1215 SequencedWorkerPoolTaskRunnerWithShutdownBehaviorTestDelegate< | |
| 1216 SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER>); | |
| 1025 | 1217 |
| 1218 template <SequencedWorkerPoolRedirection redirection> | |
| 1026 class SequencedWorkerPoolSequencedTaskRunnerTestDelegate { | 1219 class SequencedWorkerPoolSequencedTaskRunnerTestDelegate { |
| 1027 public: | 1220 public: |
| 1028 SequencedWorkerPoolSequencedTaskRunnerTestDelegate() {} | 1221 SequencedWorkerPoolSequencedTaskRunnerTestDelegate() {} |
| 1029 | 1222 |
| 1030 ~SequencedWorkerPoolSequencedTaskRunnerTestDelegate() { | 1223 ~SequencedWorkerPoolSequencedTaskRunnerTestDelegate() { |
| 1031 } | 1224 } |
| 1032 | 1225 |
| 1033 void StartTaskRunner() { | 1226 void StartTaskRunner() { |
| 1034 pool_owner_.reset(new SequencedWorkerPoolOwner( | 1227 pool_owner_.reset(new SequencedWorkerPoolOwner( |
| 1035 10, "SequencedWorkerPoolSequencedTaskRunnerTest")); | 1228 kNumWorkerThreads, "SequencedWorkerPoolSequencedTaskRunnerTest")); |
| 1036 task_runner_ = pool_owner_->pool()->GetSequencedTaskRunner( | 1229 task_runner_ = pool_owner_->pool()->GetSequencedTaskRunner( |
| 1037 pool_owner_->pool()->GetSequenceToken()); | 1230 pool_owner_->pool()->GetSequenceToken()); |
| 1231 | |
| 1232 if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) | |
| 1233 StartRedirectionToTaskScheduler(kNumWorkerThreads); | |
| 1038 } | 1234 } |
| 1039 | 1235 |
| 1040 scoped_refptr<SequencedTaskRunner> GetTaskRunner() { | 1236 scoped_refptr<SequencedTaskRunner> GetTaskRunner() { |
| 1041 return task_runner_; | 1237 return task_runner_; |
| 1042 } | 1238 } |
| 1043 | 1239 |
| 1044 void StopTaskRunner() { | 1240 void StopTaskRunner() { |
| 1045 // Make sure all tasks are run before shutting down. Delayed tasks are | 1241 pool_owner_->pool()->Shutdown(kNumAllowedBlockShutdownTasks); |
| 1046 // not run, they're simply deleted. | 1242 if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) { |
| 1047 pool_owner_->pool()->FlushForTesting(); | 1243 // When redirection to the TaskScheduler is enabled, shutting down the |
| 1048 pool_owner_->pool()->Shutdown(); | 1244 // pool is a no-op. It is necessary to shut down the TaskScheduler to make |
| 1049 // Don't reset |pool_owner_| here, as the test may still hold a | 1245 // sure that all tasks have been executed. |
| 1050 // reference to the pool. | 1246 TaskScheduler::GetInstance()->Shutdown(); |
| 1247 StopRedirectionToTaskScheduler(); | |
| 1248 } | |
| 1249 // Don't reset |pool_owner_| here, as the test may still hold a reference to | |
| 1250 // the pool. | |
| 1051 } | 1251 } |
| 1052 | 1252 |
| 1053 private: | 1253 private: |
| 1054 MessageLoop message_loop_; | 1254 MessageLoop message_loop_; |
| 1055 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_; | 1255 std::unique_ptr<SequencedWorkerPoolOwner> pool_owner_; |
| 1056 scoped_refptr<SequencedTaskRunner> task_runner_; | 1256 scoped_refptr<SequencedTaskRunner> task_runner_; |
| 1057 }; | 1257 }; |
| 1058 | 1258 |
| 1059 INSTANTIATE_TYPED_TEST_CASE_P( | 1259 INSTANTIATE_TYPED_TEST_CASE_P( |
| 1060 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerTest, | 1260 SequencedWorkerPoolSequencedTaskRunner, |
| 1061 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 1261 TaskRunnerTest, |
| 1262 SequencedWorkerPoolSequencedTaskRunnerTestDelegate< | |
| 1263 SequencedWorkerPoolRedirection::NONE>); | |
| 1062 INSTANTIATE_TYPED_TEST_CASE_P( | 1264 INSTANTIATE_TYPED_TEST_CASE_P( |
| 1063 SequencedWorkerPoolSequencedTaskRunner, TaskRunnerAffinityTest, | 1265 SequencedWorkerPoolSequencedTaskRunner, |
| 1064 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 1266 TaskRunnerAffinityTest, |
| 1267 SequencedWorkerPoolSequencedTaskRunnerTestDelegate< | |
| 1268 SequencedWorkerPoolRedirection::NONE>); | |
| 1269 INSTANTIATE_TYPED_TEST_CASE_P( | |
| 1270 SequencedWorkerPoolSequencedTaskRunnerToTaskScheduler, | |
| 1271 TaskRunnerAffinityTest, | |
| 1272 SequencedWorkerPoolSequencedTaskRunnerTestDelegate< | |
| 1273 SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER>); | |
| 1065 | 1274 |
| 1066 INSTANTIATE_TYPED_TEST_CASE_P( | 1275 INSTANTIATE_TYPED_TEST_CASE_P( |
| 1067 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest, | 1276 SequencedWorkerPoolSequencedTaskRunner, |
| 1068 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 1277 SequencedTaskRunnerTest, |
| 1278 SequencedWorkerPoolSequencedTaskRunnerTestDelegate< | |
| 1279 SequencedWorkerPoolRedirection::NONE>); | |
| 1069 INSTANTIATE_TYPED_TEST_CASE_P( | 1280 INSTANTIATE_TYPED_TEST_CASE_P( |
| 1070 SequencedWorkerPoolSequencedTaskRunner, | 1281 SequencedWorkerPoolSequencedTaskRunner, |
| 1071 SequencedTaskRunnerDelayedTest, | 1282 SequencedTaskRunnerDelayedTest, |
| 1072 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); | 1283 SequencedWorkerPoolSequencedTaskRunnerTestDelegate< |
| 1284 SequencedWorkerPoolRedirection::NONE>); | |
| 1285 | |
| 1286 // Don't run TaskRunnerTest, SequencedTaskRunnerTest and | |
|
danakj
2016/09/01 23:16:34
It feels a bit weird to make this call here, inste
| |
| 1287 // SequencedTaskRunnerDelayedTest with sequenced tasks redirected to the | |
| 1288 // TaskScheduler. These tests post tasks with and without delays which result in | |
| 1289 // getting tasks with different shutdown behaviors in the same sequence. That | |
| 1290 // isn't supported by the TaskScheduler. | |
| 1073 | 1291 |
| 1074 } // namespace | 1292 } // namespace |
| 1075 | 1293 |
| 1076 } // namespace base | 1294 } // namespace base |
| OLD | NEW |