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

Side by Side Diff: base/threading/sequenced_worker_pool_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698