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

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

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

Powered by Google App Engine
This is Rietveld 408576698