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

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

Issue 2285633003: Test SequencedWorkerPool with redirection to the TaskScheduler. (Closed)
Patch Set: CR gab/danakj #18-19 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
« no previous file with comments | « base/threading/sequenced_worker_pool.cc ('k') | chrome/browser/chrome_browser_main.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/ref_counted.h" 15 #include "base/memory/ref_counted.h"
16 #include "base/message_loop/message_loop.h" 16 #include "base/message_loop/message_loop.h"
17 #include "base/stl_util.h" 17 #include "base/stl_util.h"
18 #include "base/synchronization/condition_variable.h" 18 #include "base/synchronization/condition_variable.h"
19 #include "base/synchronization/lock.h" 19 #include "base/synchronization/lock.h"
20 #include "base/task_scheduler/scheduler_worker_pool_params.h"
21 #include "base/task_scheduler/task_scheduler.h"
22 #include "base/task_scheduler/task_scheduler_impl.h"
20 #include "base/test/sequenced_task_runner_test_template.h" 23 #include "base/test/sequenced_task_runner_test_template.h"
21 #include "base/test/sequenced_worker_pool_owner.h" 24 #include "base/test/sequenced_worker_pool_owner.h"
22 #include "base/test/task_runner_test_template.h" 25 #include "base/test/task_runner_test_template.h"
23 #include "base/test/test_timeouts.h" 26 #include "base/test/test_timeouts.h"
24 #include "base/threading/platform_thread.h" 27 #include "base/threading/platform_thread.h"
25 #include "base/time/time.h" 28 #include "base/time/time.h"
26 #include "base/tracked_objects.h" 29 #include "base/tracked_objects.h"
27 #include "testing/gtest/include/gtest/gtest.h" 30 #include "testing/gtest/include/gtest/gtest.h"
28 31
29 namespace base { 32 namespace base {
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 227
225 base::ConditionVariable cond_var_; 228 base::ConditionVariable cond_var_;
226 229
227 // Protected by lock_. 230 // Protected by lock_.
228 std::vector<int> complete_sequence_; 231 std::vector<int> complete_sequence_;
229 232
230 // Counter of the number of "block" workers that have started. 233 // Counter of the number of "block" workers that have started.
231 size_t started_events_; 234 size_t started_events_;
232 }; 235 };
233 236
234 class SequencedWorkerPoolTest : public testing::Test { 237 enum class SequencedWorkerPoolRedirection { NONE, TO_TASK_SCHEDULER };
238
239 class SequencedWorkerPoolTest
240 : public testing::TestWithParam<SequencedWorkerPoolRedirection> {
235 public: 241 public:
236 SequencedWorkerPoolTest() 242 SequencedWorkerPoolTest()
237 : tracker_(new TestTracker) { 243 : pool_owner_(new SequencedWorkerPoolOwner(kNumWorkerThreads, "test")),
238 ResetPool(); 244 tracker_(new TestTracker) {}
245
246 void SetUp() override {
247 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) {
248 std::vector<SchedulerWorkerPoolParams> worker_pool_params;
249 worker_pool_params.emplace_back(
250 "SchedulerWorkerPoolName", ThreadPriority::NORMAL,
251 SchedulerWorkerPoolParams::IORestriction::ALLOWED, kNumWorkerThreads,
252 TimeDelta::Max());
253 TaskScheduler::CreateAndSetDefaultTaskScheduler(
254 std::move(worker_pool_params),
255 base::Bind([](const TaskTraits&) -> size_t { return 0U; }));
256 SequencedWorkerPool::ResetRedirectToTaskSchedulerForProcessForTesting();
257 SequencedWorkerPool::RedirectToTaskSchedulerForProcess();
258 }
259 }
260
261 void TearDown() override {
262 // Wait until all references to the SequencedWorkerPool are gone and destroy
263 // it. This must be done before destroying the TaskScheduler. Otherwise, the
264 // SequencedWorkerPool could try to redirect tasks to a destroyed
265 // TaskScheduler.
266 DeletePool();
267
268 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) {
269 SequencedWorkerPool::ResetRedirectToTaskSchedulerForProcessForTesting();
270 DeleteTaskScheduler();
271 }
239 } 272 }
240 273
241 const scoped_refptr<SequencedWorkerPool>& pool() { 274 const scoped_refptr<SequencedWorkerPool>& pool() {
242 return pool_owner_->pool(); 275 return pool_owner_->pool();
243 } 276 }
244 TestTracker* tracker() { return tracker_.get(); } 277 TestTracker* tracker() { return tracker_.get(); }
245 278
246 // Destroys the SequencedWorkerPool instance, blocking until it is fully shut 279 // Waits until no tasks are running in the SequencedWorkerPool and no
247 // down, and creates a new instance. 280 // reference to it remain. Then, destroys the SequencedWorkerPool.
248 void ResetPool() { 281 void DeletePool() { pool_owner_.reset(); }
249 pool_owner_.reset(new SequencedWorkerPoolOwner(kNumWorkerThreads, "test")); 282
283 // Destroys and unregisters the registered TaskScheduler, if any.
284 void DeleteTaskScheduler() {
285 if (TaskScheduler::GetInstance()) {
286 static_cast<internal::TaskSchedulerImpl*>(TaskScheduler::GetInstance())
287 ->JoinForTesting();
288 TaskScheduler::SetInstance(nullptr);
289 }
250 } 290 }
251 291
252 void SetWillWaitForShutdownCallback(const Closure& callback) { 292 void SetWillWaitForShutdownCallback(const Closure& callback) {
253 pool_owner_->SetWillWaitForShutdownCallback(callback); 293 pool_owner_->SetWillWaitForShutdownCallback(callback);
254 } 294 }
255 295
256 // Ensures that the given number of worker threads is created by adding 296 // Ensures that the given number of worker threads is created by adding
257 // tasks and waiting until they complete. Worker thread creation is 297 // tasks and waiting until they complete. Worker thread creation is
258 // serialized, can happen on background threads asynchronously, and doesn't 298 // serialized, can happen on background threads asynchronously, and doesn't
259 // happen any more at shutdown. This means that if a test posts a bunch of 299 // happen any more at shutdown. This means that if a test posts a bunch of
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 } 359 }
320 360
321 private: 361 private:
322 friend class base::RefCountedThreadSafe<DeletionHelper>; 362 friend class base::RefCountedThreadSafe<DeletionHelper>;
323 virtual ~DeletionHelper() { deleted_flag_->data = true; } 363 virtual ~DeletionHelper() { deleted_flag_->data = true; }
324 364
325 const scoped_refptr<base::RefCountedData<bool> > deleted_flag_; 365 const scoped_refptr<base::RefCountedData<bool> > deleted_flag_;
326 DISALLOW_COPY_AND_ASSIGN(DeletionHelper); 366 DISALLOW_COPY_AND_ASSIGN(DeletionHelper);
327 }; 367 };
328 368
329 void HoldPoolReference(const scoped_refptr<base::SequencedWorkerPool>& pool, 369 void ShouldNotRun(const scoped_refptr<DeletionHelper>& helper) {
330 const scoped_refptr<DeletionHelper>& helper) {
331 ADD_FAILURE() << "Should never run"; 370 ADD_FAILURE() << "Should never run";
332 } 371 }
333 372
334 // Tests that delayed tasks are deleted upon shutdown of the pool. 373 // Tests that shutdown does not wait for delayed tasks.
335 TEST_F(SequencedWorkerPoolTest, DelayedTaskDuringShutdown) { 374 TEST_P(SequencedWorkerPoolTest, DelayedTaskDuringShutdown) {
336 // Post something to verify the pool is started up. 375 // Post something to verify the pool is started up.
337 EXPECT_TRUE(pool()->PostTask( 376 EXPECT_TRUE(pool()->PostTask(
338 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 1))); 377 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 1)));
339 378
340 scoped_refptr<base::RefCountedData<bool> > deleted_flag( 379 scoped_refptr<base::RefCountedData<bool> > deleted_flag(
341 new base::RefCountedData<bool>(false)); 380 new base::RefCountedData<bool>(false));
342 381
343 base::Time posted_at(base::Time::Now()); 382 base::Time posted_at(base::Time::Now());
344 // Post something that shouldn't run. 383 // Post something that shouldn't run.
345 EXPECT_TRUE(pool()->PostDelayedTask( 384 EXPECT_TRUE(pool()->PostDelayedTask(
346 FROM_HERE, 385 FROM_HERE,
347 base::Bind(&HoldPoolReference, 386 base::Bind(&ShouldNotRun,
348 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 // Shutdown the pool.
357 // fully destroyed (and thus shut down). 395 pool()->Shutdown();
358 ResetPool(); 396 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
397 TaskScheduler::GetInstance()->Shutdown();
359 398
360 // Verify that we didn't block until the task was due. 399 // Verify that we didn't block until the task was due.
361 ASSERT_LT(base::Time::Now() - posted_at, TestTimeouts::action_timeout()); 400 ASSERT_LT(base::Time::Now() - posted_at, TestTimeouts::action_timeout());
362 401
363 // Verify that the deferred task has not only not run, but has also been 402 // Verify that the delayed task is deleted when the SequencedWorkerPool (and
364 // destroyed. 403 // the TaskScheduler when applicable) are deleted.
365 ASSERT_TRUE(deleted_flag->data); 404 EXPECT_FALSE(deleted_flag->data);
405 DeletePool();
406 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
407 DeleteTaskScheduler();
408 EXPECT_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 // As tested by TaskSchedulerTaskTrackerTest.WillPostAndRunDuringShutdown,
591 // TaskScheduler allows tasks to be posted during shutdown. However, since it
592 // doesn't provide a way to run a callback from inside its Shutdown() method,
593 // 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 // As tested by TaskSchedulerTaskTrackerTest.WillPostAndRunDuringShutdown,
645 // TaskScheduler allows tasks to be posted during shutdown. However, since it
646 // doesn't provide a way to run a callback from inside its Shutdown() method,
647 // 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 // As tested by
679 // TaskSchedulerTaskTrackerTest.WillPostBeforeShutdownRunDuringShutdown, on
680 // shutdown, the TaskScheduler discards SKIP_ON_SHUTDOWN and
681 // CONTINUE_ON_SHUTDOWN tasks and runs BLOCK_SHUTDOWN tasks. However, since it
682 // doesn't provide a way to run a callback from inside its Shutdown() method,
683 // it would be hard to make this test work with redirection enabled.
684 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
685 return;
686
621 // Start tasks to take all the threads and block them. 687 // Start tasks to take all the threads and block them.
622 EnsureAllWorkersCreated(); 688 EnsureAllWorkersCreated();
623 ThreadBlocker blocker; 689 ThreadBlocker blocker;
624 for (size_t i = 0; i < kNumWorkerThreads; i++) { 690 for (size_t i = 0; i < kNumWorkerThreads; i++) {
625 pool()->PostWorkerTask(FROM_HERE, 691 pool()->PostWorkerTask(FROM_HERE,
626 base::Bind(&TestTracker::BlockTask, 692 base::Bind(&TestTracker::BlockTask,
627 tracker(), i, &blocker)); 693 tracker(), i, &blocker));
628 } 694 }
629 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); 695 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads);
630 696
(...skipping 23 matching lines...) Expand all
654 720
655 // The kNumWorkerThread items should have completed, plus the BLOCK_SHUTDOWN 721 // The kNumWorkerThread items should have completed, plus the BLOCK_SHUTDOWN
656 // one, in no particular order. 722 // one, in no particular order.
657 ASSERT_EQ(kNumWorkerThreads + 1, result.size()); 723 ASSERT_EQ(kNumWorkerThreads + 1, result.size());
658 for (size_t i = 0; i < kNumWorkerThreads; i++) 724 for (size_t i = 0; i < kNumWorkerThreads; i++)
659 EXPECT_TRUE(ContainsValue(result, static_cast<int>(i))); 725 EXPECT_TRUE(ContainsValue(result, static_cast<int>(i)));
660 EXPECT_TRUE(ContainsValue(result, 102)); 726 EXPECT_TRUE(ContainsValue(result, 102));
661 } 727 }
662 728
663 // Tests that CONTINUE_ON_SHUTDOWN tasks don't block shutdown. 729 // Tests that CONTINUE_ON_SHUTDOWN tasks don't block shutdown.
664 TEST_F(SequencedWorkerPoolTest, ContinueOnShutdown) { 730 TEST_P(SequencedWorkerPoolTest, ContinueOnShutdown) {
665 scoped_refptr<TaskRunner> runner(pool()->GetTaskRunnerWithShutdownBehavior( 731 scoped_refptr<TaskRunner> runner(pool()->GetTaskRunnerWithShutdownBehavior(
666 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); 732 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN));
667 scoped_refptr<SequencedTaskRunner> sequenced_runner( 733 scoped_refptr<SequencedTaskRunner> sequenced_runner(
668 pool()->GetSequencedTaskRunnerWithShutdownBehavior( 734 pool()->GetSequencedTaskRunnerWithShutdownBehavior(
669 pool()->GetSequenceToken(), 735 pool()->GetSequenceToken(),
670 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); 736 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN));
671 EnsureAllWorkersCreated(); 737 EnsureAllWorkersCreated();
672 ThreadBlocker blocker; 738 ThreadBlocker blocker;
673 pool()->PostWorkerTaskWithShutdownBehavior( 739 pool()->PostWorkerTaskWithShutdownBehavior(
674 FROM_HERE, 740 FROM_HERE,
675 base::Bind(&TestTracker::BlockTask, 741 base::Bind(&TestTracker::BlockTask,
676 tracker(), 0, &blocker), 742 tracker(), 0, &blocker),
677 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); 743 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
678 runner->PostTask( 744 runner->PostTask(
679 FROM_HERE, 745 FROM_HERE,
680 base::Bind(&TestTracker::BlockTask, 746 base::Bind(&TestTracker::BlockTask,
681 tracker(), 1, &blocker)); 747 tracker(), 1, &blocker));
682 sequenced_runner->PostTask( 748 sequenced_runner->PostTask(
683 FROM_HERE, 749 FROM_HERE,
684 base::Bind(&TestTracker::BlockTask, 750 base::Bind(&TestTracker::BlockTask,
685 tracker(), 2, &blocker)); 751 tracker(), 2, &blocker));
686 752
687 tracker()->WaitUntilTasksBlocked(3); 753 tracker()->WaitUntilTasksBlocked(3);
688 754
689 // This should not block. If this test hangs, it means it failed. 755 // This should not block. If this test hangs, it means it failed.
690 pool()->Shutdown(); 756 pool()->Shutdown();
757 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
758 TaskScheduler::GetInstance()->Shutdown();
691 759
692 // The task should not have completed yet. 760 // The task should not have completed yet.
693 EXPECT_EQ(0u, tracker()->WaitUntilTasksComplete(0).size()); 761 EXPECT_EQ(0u, tracker()->WaitUntilTasksComplete(0).size());
694 762
695 // Posting more tasks should fail. 763 // Posting more tasks should fail.
696 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior( 764 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior(
697 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0), 765 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0),
698 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)); 766 SequencedWorkerPool::CONTINUE_ON_SHUTDOWN));
699 EXPECT_FALSE(runner->PostTask( 767 EXPECT_FALSE(runner->PostTask(
700 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0))); 768 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0)));
701 EXPECT_FALSE(sequenced_runner->PostTask( 769 EXPECT_FALSE(sequenced_runner->PostTask(
702 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0))); 770 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 0)));
703 771
704 // Continue the background thread and make sure the tasks can complete. 772 // Continue the background thread and make sure the tasks can complete.
705 blocker.Unblock(3); 773 blocker.Unblock(3);
706 std::vector<int> result = tracker()->WaitUntilTasksComplete(3); 774 std::vector<int> result = tracker()->WaitUntilTasksComplete(3);
707 EXPECT_EQ(3u, result.size()); 775 EXPECT_EQ(3u, result.size());
708 } 776 }
709 777
710 // Tests that SKIP_ON_SHUTDOWN tasks that have been started block Shutdown 778 // Tests that SKIP_ON_SHUTDOWN tasks that have been started block Shutdown
711 // until they stop, but tasks not yet started do not. 779 // until they stop, but tasks not yet started do not.
712 TEST_F(SequencedWorkerPoolTest, SkipOnShutdown) { 780 TEST_P(SequencedWorkerPoolTest, SkipOnShutdown) {
781 // As tested by
782 // TaskSchedulerTaskTrackerTest.WillPostAndRunLongTaskBeforeShutdown and
783 // TaskSchedulerTaskTrackerTest.WillPostBeforeShutdownRunDuringShutdown, the
784 // TaskScheduler correctly handles SKIP_ON_SHUTDOWN tasks. However, since it
785 // doesn't provide a way to run a callback from inside its Shutdown() method,
786 // it would be hard to make this test work with redirection 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 VerifyRunsTasksOnCurrentThread( 853 void VerifyRunsTasksOnCurrentThread(
854 SequencedWorkerPoolRedirection redirection,
773 scoped_refptr<TaskRunner> test_positive_task_runner, 855 scoped_refptr<TaskRunner> test_positive_task_runner,
774 scoped_refptr<TaskRunner> test_negative_task_runner, 856 scoped_refptr<TaskRunner> test_negative_task_runner,
775 SequencedWorkerPool* pool, 857 SequencedWorkerPool* pool,
776 SequencedWorkerPool* unused_pool) { 858 SequencedWorkerPool* unused_pool) {
777 EXPECT_TRUE(test_positive_task_runner->RunsTasksOnCurrentThread()); 859 EXPECT_TRUE(test_positive_task_runner->RunsTasksOnCurrentThread());
778 EXPECT_FALSE(test_negative_task_runner->RunsTasksOnCurrentThread()); 860 EXPECT_FALSE(test_negative_task_runner->RunsTasksOnCurrentThread());
779 EXPECT_TRUE(pool->RunsTasksOnCurrentThread()); 861 EXPECT_TRUE(pool->RunsTasksOnCurrentThread());
780 EXPECT_FALSE(unused_pool->RunsTasksOnCurrentThread()); 862
863 // Tasks posted to different SequencedWorkerPools may run on the same
864 // TaskScheduler threads.
865 if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
866 EXPECT_TRUE(unused_pool->RunsTasksOnCurrentThread());
867 else
868 EXPECT_FALSE(unused_pool->RunsTasksOnCurrentThread());
781 } 869 }
782 870
783 // Verify correctness of the RunsTasksOnCurrentThread() method on 871 // Verify correctness of the RunsTasksOnCurrentThread() method on
784 // SequencedWorkerPool and on TaskRunners it returns. 872 // SequencedWorkerPool and on TaskRunners it returns.
785 TEST_F(SequencedWorkerPoolTest, RunsTasksOnCurrentThread) { 873 TEST_P(SequencedWorkerPoolTest, RunsTasksOnCurrentThread) {
786 const scoped_refptr<SequencedTaskRunner> sequenced_task_runner_1 = 874 const scoped_refptr<SequencedTaskRunner> sequenced_task_runner_1 =
787 pool()->GetSequencedTaskRunner(SequencedWorkerPool::GetSequenceToken()); 875 pool()->GetSequencedTaskRunner(SequencedWorkerPool::GetSequenceToken());
788 const scoped_refptr<SequencedTaskRunner> sequenced_task_runner_2 = 876 const scoped_refptr<SequencedTaskRunner> sequenced_task_runner_2 =
789 pool()->GetSequencedTaskRunner(SequencedWorkerPool::GetSequenceToken()); 877 pool()->GetSequencedTaskRunner(SequencedWorkerPool::GetSequenceToken());
790 const scoped_refptr<TaskRunner> unsequenced_task_runner = 878 const scoped_refptr<TaskRunner> unsequenced_task_runner =
791 pool()->GetTaskRunnerWithShutdownBehavior( 879 pool()->GetTaskRunnerWithShutdownBehavior(
792 SequencedWorkerPool::BLOCK_SHUTDOWN); 880 SequencedWorkerPool::BLOCK_SHUTDOWN);
793 881
794 SequencedWorkerPoolOwner unused_pool_owner(2, "unused_pool"); 882 SequencedWorkerPoolOwner unused_pool_owner(2, "unused_pool");
795 883
796 EXPECT_FALSE(pool()->RunsTasksOnCurrentThread()); 884 EXPECT_FALSE(pool()->RunsTasksOnCurrentThread());
797 EXPECT_FALSE(sequenced_task_runner_1->RunsTasksOnCurrentThread()); 885 EXPECT_FALSE(sequenced_task_runner_1->RunsTasksOnCurrentThread());
798 EXPECT_FALSE(sequenced_task_runner_2->RunsTasksOnCurrentThread()); 886 EXPECT_FALSE(sequenced_task_runner_2->RunsTasksOnCurrentThread());
799 EXPECT_FALSE(unsequenced_task_runner->RunsTasksOnCurrentThread()); 887 EXPECT_FALSE(unsequenced_task_runner->RunsTasksOnCurrentThread());
800 EXPECT_FALSE(unused_pool_owner.pool()->RunsTasksOnCurrentThread()); 888 EXPECT_FALSE(unused_pool_owner.pool()->RunsTasksOnCurrentThread());
801 889
802 // From a task posted to |sequenced_task_runner_1|: 890 // From a task posted to |sequenced_task_runner_1|:
803 // - sequenced_task_runner_1->RunsTasksOnCurrentThread() returns true. 891 // - sequenced_task_runner_1->RunsTasksOnCurrentThread() returns true.
804 // - sequenced_task_runner_2->RunsTasksOnCurrentThread() returns false. 892 // - sequenced_task_runner_2->RunsTasksOnCurrentThread() returns false.
805 // - pool()->RunsTasksOnCurrentThread() returns true. 893 // - pool()->RunsTasksOnCurrentThread() returns true.
806 // - unused_pool_owner.pool()->RunsTasksOnCurrentThread() returns false. 894 // - unused_pool_owner.pool()->RunsTasksOnCurrentThread() returns false.
807 sequenced_task_runner_1->PostTask( 895 sequenced_task_runner_1->PostTask(
808 FROM_HERE, 896 FROM_HERE, base::Bind(&VerifyRunsTasksOnCurrentThread, GetParam(),
809 base::Bind(&VerifyRunsTasksOnCurrentThread, sequenced_task_runner_1, 897 sequenced_task_runner_1, sequenced_task_runner_2,
810 sequenced_task_runner_2, base::RetainedRef(pool()), 898 base::RetainedRef(pool()),
811 base::RetainedRef(unused_pool_owner.pool()))); 899 base::RetainedRef(unused_pool_owner.pool())));
812 // From a task posted to |unsequenced_task_runner|: 900 // From a task posted to |unsequenced_task_runner|:
813 // - unsequenced_task_runner->RunsTasksOnCurrentThread() returns true. 901 // - unsequenced_task_runner->RunsTasksOnCurrentThread() returns true.
814 // - sequenced_task_runner_1->RunsTasksOnCurrentThread() returns false. 902 // - sequenced_task_runner_1->RunsTasksOnCurrentThread() returns false.
815 // - pool()->RunsTasksOnCurrentThread() returns true. 903 // - pool()->RunsTasksOnCurrentThread() returns true.
816 // - unused_pool_owner.pool()->RunsTasksOnCurrentThread() returns false. 904 // - unused_pool_owner.pool()->RunsTasksOnCurrentThread() returns false.
817 unsequenced_task_runner->PostTask( 905 unsequenced_task_runner->PostTask(
818 FROM_HERE, 906 FROM_HERE, base::Bind(&VerifyRunsTasksOnCurrentThread, GetParam(),
819 base::Bind(&VerifyRunsTasksOnCurrentThread, unsequenced_task_runner, 907 unsequenced_task_runner, sequenced_task_runner_1,
820 sequenced_task_runner_1, base::RetainedRef(pool()), 908 base::RetainedRef(pool()),
821 base::RetainedRef(unused_pool_owner.pool()))); 909 base::RetainedRef(unused_pool_owner.pool())));
822 } 910 }
823 911
824 // 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
825 // task is destroyed while SequencedWorkerPool's global lock is held, 913 // task is destroyed while SequencedWorkerPool's global lock is held,
826 // SequencedWorkerPool might deadlock. 914 // SequencedWorkerPool might deadlock.
827 TEST_F(SequencedWorkerPoolTest, AvoidsDeadlockOnShutdown) { 915 TEST_P(SequencedWorkerPoolTest, AvoidsDeadlockOnShutdown) {
916 // Note: TaskScheduler destroys tasks when it is deleted rather than on
917 // shutdown. In production, it should never be destroyed.
918
828 for (int i = 0; i < 4; ++i) { 919 for (int i = 0; i < 4; ++i) {
829 scoped_refptr<DestructionDeadlockChecker> checker( 920 scoped_refptr<DestructionDeadlockChecker> checker(
830 new DestructionDeadlockChecker(pool())); 921 new DestructionDeadlockChecker(pool()));
831 tracker()->PostRepostingTask(pool(), checker); 922 tracker()->PostRepostingTask(pool(), checker);
832 } 923 }
833 924
834 // Shutting down the pool should destroy the DestructionDeadlockCheckers, 925 // Shutting down the pool should destroy the DestructionDeadlockCheckers,
835 // which in turn should not deadlock in their destructors. 926 // which in turn should not deadlock in their destructors.
836 pool()->Shutdown(); 927 pool()->Shutdown();
837 } 928 }
838 929
839 // Similar to the test AvoidsDeadlockOnShutdown, but there are now also 930 // Similar to the test AvoidsDeadlockOnShutdown, but there are now also
840 // sequenced, blocking tasks in the queue during shutdown. 931 // sequenced, blocking tasks in the queue during shutdown.
841 TEST_F(SequencedWorkerPoolTest, 932 TEST_P(SequencedWorkerPoolTest,
842 AvoidsDeadlockOnShutdownWithSequencedBlockingTasks) { 933 AvoidsDeadlockOnShutdownWithSequencedBlockingTasks) {
934 // This test continuously posts BLOCK_SHUTDOWN tasks
935 // (PostRepostingBlockingTask). It can't run when tasks are redirected to
936 // TaskScheduler because TaskScheduler doesn't provide a way to limit the
937 // number of BLOCK_SHUTDOWN tasks posted during shutdown.
938 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
939 return;
940
843 const std::string sequence_token_name("name"); 941 const std::string sequence_token_name("name");
844 for (int i = 0; i < 4; ++i) { 942 for (int i = 0; i < 4; ++i) {
845 scoped_refptr<DestructionDeadlockChecker> checker( 943 scoped_refptr<DestructionDeadlockChecker> checker(
846 new DestructionDeadlockChecker(pool())); 944 new DestructionDeadlockChecker(pool()));
847 tracker()->PostRepostingTask(pool(), checker); 945 tracker()->PostRepostingTask(pool(), checker);
848 946
849 SequencedWorkerPool::SequenceToken token1 = 947 SequencedWorkerPool::SequenceToken token1 =
850 pool()->GetNamedSequenceToken(sequence_token_name); 948 pool()->GetNamedSequenceToken(sequence_token_name);
851 tracker()->PostRepostingBlockingTask(pool(), token1); 949 tracker()->PostRepostingBlockingTask(pool(), token1);
852 } 950 }
853 951
854 // Shutting down the pool should destroy the DestructionDeadlockCheckers, 952 // Shutting down the pool should destroy the DestructionDeadlockCheckers,
855 // which in turn should not deadlock in their destructors. 953 // which in turn should not deadlock in their destructors.
856 pool()->Shutdown(); 954 pool()->Shutdown();
857 } 955 }
858 956
859 // Verify that FlushForTesting works as intended. 957 // Verify that FlushForTesting works as intended.
860 TEST_F(SequencedWorkerPoolTest, FlushForTesting) { 958 TEST_P(SequencedWorkerPoolTest, FlushForTesting) {
959 // FlushForTesting() can't be called when tasks are redirected to the
960 // TaskScheduler.
961 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
962 return;
963
861 // Should be fine to call on a new instance. 964 // Should be fine to call on a new instance.
862 pool()->FlushForTesting(); 965 pool()->FlushForTesting();
863 966
864 // 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
865 // a task that produces additional tasks as an artifact. 968 // a task that produces additional tasks as an artifact.
866 pool()->PostDelayedWorkerTask( 969 pool()->PostDelayedWorkerTask(
867 FROM_HERE, 970 FROM_HERE,
868 base::Bind(&TestTracker::FastTask, tracker(), 0), 971 base::Bind(&TestTracker::FastTask, tracker(), 0),
869 TimeDelta::FromMinutes(5)); 972 TimeDelta::FromMinutes(5));
870 pool()->PostWorkerTask(FROM_HERE, 973 pool()->PostWorkerTask(FROM_HERE,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 SequencedWorkerPool::GetSequenceTokenForCurrentThread(); 1008 SequencedWorkerPool::GetSequenceTokenForCurrentThread();
906 EXPECT_EQ(expected_token.ToString(), token.ToString()); 1009 EXPECT_EQ(expected_token.ToString(), token.ToString());
907 1010
908 scoped_refptr<SequencedWorkerPool> pool = 1011 scoped_refptr<SequencedWorkerPool> pool =
909 SequencedWorkerPool::GetWorkerPoolForCurrentThread(); 1012 SequencedWorkerPool::GetWorkerPoolForCurrentThread();
910 EXPECT_EQ(expected_pool, pool); 1013 EXPECT_EQ(expected_pool, pool);
911 } 1014 }
912 1015
913 } // namespace 1016 } // namespace
914 1017
915 TEST_F(SequencedWorkerPoolTest, GetWorkerPoolAndSequenceTokenForCurrentThread) { 1018 TEST_P(SequencedWorkerPoolTest, GetWorkerPoolAndSequenceTokenForCurrentThread) {
1019 // GetSequenceTokenForCurrentThread() and GetWorkerPoolForCurrentThread()
1020 // respectively return an invalid token and nullptr from a task posted to a
1021 // SequencedWorkerPool when redirection to TaskScheduler is enabled. These
1022 // methods are only used from SequencedTaskRunnerHandle and
1023 // SequenceCheckerImpl which work fine in TaskScheduler.
1024 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
1025 return;
1026
916 EnsureAllWorkersCreated(); 1027 EnsureAllWorkersCreated();
917 1028
918 // The current thread should have neither a worker pool nor a sequence token. 1029 // The current thread should have neither a worker pool nor a sequence token.
919 SequencedWorkerPool::SequenceToken local_token = 1030 SequencedWorkerPool::SequenceToken local_token =
920 SequencedWorkerPool::GetSequenceTokenForCurrentThread(); 1031 SequencedWorkerPool::GetSequenceTokenForCurrentThread();
921 scoped_refptr<SequencedWorkerPool> local_pool = 1032 scoped_refptr<SequencedWorkerPool> local_pool =
922 SequencedWorkerPool::GetWorkerPoolForCurrentThread(); 1033 SequencedWorkerPool::GetWorkerPoolForCurrentThread();
923 EXPECT_FALSE(local_token.IsValid()) << local_token.ToString(); 1034 EXPECT_FALSE(local_token.IsValid()) << local_token.ToString();
924 EXPECT_FALSE(local_pool); 1035 EXPECT_FALSE(local_pool);
925 1036
926 SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken(); 1037 SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken();
927 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken(); 1038 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken();
928 pool()->PostSequencedWorkerTask( 1039 pool()->PostSequencedWorkerTask(
929 token1, FROM_HERE, 1040 token1, FROM_HERE,
930 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token1)); 1041 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token1));
931 pool()->PostSequencedWorkerTask( 1042 pool()->PostSequencedWorkerTask(
932 token2, FROM_HERE, 1043 token2, FROM_HERE,
933 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token2)); 1044 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token2));
934 1045
935 pool()->PostWorkerTask(FROM_HERE, 1046 pool()->PostWorkerTask(FROM_HERE,
936 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), 1047 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(),
937 SequencedWorkerPool::SequenceToken())); 1048 SequencedWorkerPool::SequenceToken()));
938 1049
939 pool()->FlushForTesting(); 1050 pool()->FlushForTesting();
940 } 1051 }
941 1052
942 TEST_F(SequencedWorkerPoolTest, ShutsDownCleanWithContinueOnShutdown) { 1053 TEST_P(SequencedWorkerPoolTest, ShutsDownCleanWithContinueOnShutdown) {
943 scoped_refptr<SequencedTaskRunner> task_runner = 1054 scoped_refptr<SequencedTaskRunner> task_runner =
944 pool()->GetSequencedTaskRunnerWithShutdownBehavior( 1055 pool()->GetSequencedTaskRunnerWithShutdownBehavior(
945 pool()->GetSequenceToken(), 1056 pool()->GetSequenceToken(),
946 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); 1057 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
947 1058
948 // Upon test exit, should shut down without hanging. 1059 // Upon test exit, should shut down without hanging.
949 pool()->Shutdown(); 1060 pool()->Shutdown();
950 } 1061 }
951 1062
1063 INSTANTIATE_TEST_CASE_P(
1064 NoRedirection,
1065 SequencedWorkerPoolTest,
1066 ::testing::Values(SequencedWorkerPoolRedirection::NONE));
1067 INSTANTIATE_TEST_CASE_P(
1068 RedirectionToTaskScheduler,
1069 SequencedWorkerPoolTest,
1070 ::testing::Values(SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER));
1071
952 class SequencedWorkerPoolTaskRunnerTestDelegate { 1072 class SequencedWorkerPoolTaskRunnerTestDelegate {
953 public: 1073 public:
954 SequencedWorkerPoolTaskRunnerTestDelegate() {} 1074 SequencedWorkerPoolTaskRunnerTestDelegate() {}
955 1075
956 ~SequencedWorkerPoolTaskRunnerTestDelegate() {} 1076 ~SequencedWorkerPoolTaskRunnerTestDelegate() {}
957 1077
958 void StartTaskRunner() { 1078 void StartTaskRunner() {
959 pool_owner_.reset( 1079 pool_owner_.reset(
960 new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest")); 1080 new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest"));
961 } 1081 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest, 1188 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest,
1069 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); 1189 SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
1070 INSTANTIATE_TYPED_TEST_CASE_P( 1190 INSTANTIATE_TYPED_TEST_CASE_P(
1071 SequencedWorkerPoolSequencedTaskRunner, 1191 SequencedWorkerPoolSequencedTaskRunner,
1072 SequencedTaskRunnerDelayedTest, 1192 SequencedTaskRunnerDelayedTest,
1073 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); 1193 SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
1074 1194
1075 } // namespace 1195 } // namespace
1076 1196
1077 } // namespace base 1197 } // namespace base
OLDNEW
« no previous file with comments | « base/threading/sequenced_worker_pool.cc ('k') | chrome/browser/chrome_browser_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698