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

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

Issue 2285633003: Test SequencedWorkerPool with redirection to the TaskScheduler. (Closed)
Patch Set: Rewrote everything 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 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; }));
danakj 2016/09/16 20:29:36 do you need the -> size_t here? something like it
fdoray 2016/09/16 21:21:31 doesn't compile without the -> size_t
256 SequencedWorkerPool::ResetRedirectToTaskSchedulerForProcessForTesting();
257 SequencedWorkerPool::RedirectToTaskSchedulerForProcess();
258 }
259 }
260
261 void TearDown() override {
262 // Destroy the SequencedWorkerPool before the TaskScheduler.
danakj 2016/09/16 20:29:36 say why instead of just what
fdoray 2016/09/16 21:21:31 Done.
263 DeletePool();
264
265 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER) {
266 SequencedWorkerPool::ResetRedirectToTaskSchedulerForProcessForTesting();
267 DeleteTaskScheduler();
268 }
239 } 269 }
240 270
241 const scoped_refptr<SequencedWorkerPool>& pool() { 271 const scoped_refptr<SequencedWorkerPool>& pool() {
242 return pool_owner_->pool(); 272 return pool_owner_->pool();
243 } 273 }
244 TestTracker* tracker() { return tracker_.get(); } 274 TestTracker* tracker() { return tracker_.get(); }
245 275
246 // Destroys the SequencedWorkerPool instance, blocking until it is fully shut 276 // Destroys the SequencedWorkerPool instance, blocking until it is fully shut
247 // down, and creates a new instance. 277 // down, and creates a new instance.
danakj 2016/09/16 20:29:36 comment wrong now
fdoray 2016/09/16 21:21:31 Done.
248 void ResetPool() { 278 void DeletePool() { pool_owner_ = nullptr; }
gab 2016/09/16 20:16:10 pool_owner_.reset()
fdoray 2016/09/16 21:21:31 Done.
249 pool_owner_.reset(new SequencedWorkerPoolOwner(kNumWorkerThreads, "test")); 279
280 // Destroys and unregisters the registered TaskScheduler, if any.
281 void DeleteTaskScheduler() {
282 if (TaskScheduler::GetInstance()) {
283 static_cast<internal::TaskSchedulerImpl*>(TaskScheduler::GetInstance())
284 ->JoinForTesting();
gab 2016/09/16 20:16:10 Should we add TaskScheduler::JoinForTesting?
fdoray 2016/09/16 21:21:31 I don't think we want every test that needs a Task
285 TaskScheduler::SetInstance(nullptr);
286 }
250 } 287 }
251 288
252 void SetWillWaitForShutdownCallback(const Closure& callback) { 289 void SetWillWaitForShutdownCallback(const Closure& callback) {
253 pool_owner_->SetWillWaitForShutdownCallback(callback); 290 pool_owner_->SetWillWaitForShutdownCallback(callback);
254 } 291 }
255 292
256 // Ensures that the given number of worker threads is created by adding 293 // Ensures that the given number of worker threads is created by adding
257 // tasks and waiting until they complete. Worker thread creation is 294 // tasks and waiting until they complete. Worker thread creation is
258 // serialized, can happen on background threads asynchronously, and doesn't 295 // 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 296 // 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 } 356 }
320 357
321 private: 358 private:
322 friend class base::RefCountedThreadSafe<DeletionHelper>; 359 friend class base::RefCountedThreadSafe<DeletionHelper>;
323 virtual ~DeletionHelper() { deleted_flag_->data = true; } 360 virtual ~DeletionHelper() { deleted_flag_->data = true; }
324 361
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 ShouldNotRun(const scoped_refptr<DeletionHelper>& helper) {
330 const scoped_refptr<DeletionHelper>& helper) {
331 ADD_FAILURE() << "Should never run"; 367 ADD_FAILURE() << "Should never run";
332 } 368 }
333 369
334 // Tests that delayed tasks are deleted upon shutdown of the pool. 370 // Tests that shutdown does not wait for delayed tasks.
335 TEST_F(SequencedWorkerPoolTest, DelayedTaskDuringShutdown) { 371 TEST_P(SequencedWorkerPoolTest, DelayedTaskDuringShutdown) {
336 // Post something to verify the pool is started up. 372 // Post something to verify the pool is started up.
337 EXPECT_TRUE(pool()->PostTask( 373 EXPECT_TRUE(pool()->PostTask(
338 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 1))); 374 FROM_HERE, base::Bind(&TestTracker::FastTask, tracker(), 1)));
339 375
340 scoped_refptr<base::RefCountedData<bool> > deleted_flag( 376 scoped_refptr<base::RefCountedData<bool> > deleted_flag(
341 new base::RefCountedData<bool>(false)); 377 new base::RefCountedData<bool>(false));
342 378
343 base::Time posted_at(base::Time::Now()); 379 base::Time posted_at(base::Time::Now());
344 // Post something that shouldn't run. 380 // Post something that shouldn't run.
345 EXPECT_TRUE(pool()->PostDelayedTask( 381 EXPECT_TRUE(pool()->PostDelayedTask(
346 FROM_HERE, 382 FROM_HERE,
347 base::Bind(&HoldPoolReference, 383 base::Bind(&ShouldNotRun,
348 pool(),
349 make_scoped_refptr(new DeletionHelper(deleted_flag))), 384 make_scoped_refptr(new DeletionHelper(deleted_flag))),
350 TestTimeouts::action_timeout())); 385 TestTimeouts::action_timeout()));
351 386
352 std::vector<int> completion_sequence = tracker()->WaitUntilTasksComplete(1); 387 std::vector<int> completion_sequence = tracker()->WaitUntilTasksComplete(1);
353 ASSERT_EQ(1u, completion_sequence.size()); 388 ASSERT_EQ(1u, completion_sequence.size());
354 ASSERT_EQ(1, completion_sequence[0]); 389 ASSERT_EQ(1, completion_sequence[0]);
355 390
356 // Shutdown is asynchronous, so use ResetPool() to block until the pool is 391 // Shutdown the pool.
357 // fully destroyed (and thus shut down). 392 pool()->Shutdown();
358 ResetPool(); 393 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
394 TaskScheduler::GetInstance()->Shutdown();
359 395
360 // Verify that we didn't block until the task was due. 396 // Verify that we didn't block until the task was due.
361 ASSERT_LT(base::Time::Now() - posted_at, TestTimeouts::action_timeout()); 397 ASSERT_LT(base::Time::Now() - posted_at, TestTimeouts::action_timeout());
362 398
363 // Verify that the deferred task has not only not run, but has also been 399 // Verify that the delayed task is deleted when the SequencedWorkerPool (and
364 // destroyed. 400 // the TaskScheduler when applicable) are deleted.
365 ASSERT_TRUE(deleted_flag->data); 401 EXPECT_FALSE(deleted_flag->data);
402 DeletePool();
403 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
404 DeleteTaskScheduler();
405 EXPECT_TRUE(deleted_flag->data);
366 } 406 }
367 407
368 // Tests that same-named tokens have the same ID. 408 // Tests that same-named tokens have the same ID.
369 TEST_F(SequencedWorkerPoolTest, NamedTokens) { 409 TEST_P(SequencedWorkerPoolTest, NamedTokens) {
370 const std::string name1("hello"); 410 const std::string name1("hello");
371 SequencedWorkerPool::SequenceToken token1 = 411 SequencedWorkerPool::SequenceToken token1 =
372 pool()->GetNamedSequenceToken(name1); 412 pool()->GetNamedSequenceToken(name1);
373 413
374 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken(); 414 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken();
375 415
376 const std::string name3("goodbye"); 416 const std::string name3("goodbye");
377 SequencedWorkerPool::SequenceToken token3 = 417 SequencedWorkerPool::SequenceToken token3 =
378 pool()->GetNamedSequenceToken(name3); 418 pool()->GetNamedSequenceToken(name3);
379 419
380 // All 3 tokens should be different. 420 // All 3 tokens should be different.
381 EXPECT_FALSE(token1.Equals(token2)); 421 EXPECT_FALSE(token1.Equals(token2));
382 EXPECT_FALSE(token1.Equals(token3)); 422 EXPECT_FALSE(token1.Equals(token3));
383 EXPECT_FALSE(token2.Equals(token3)); 423 EXPECT_FALSE(token2.Equals(token3));
384 424
385 // Requesting the same name again should give the same value. 425 // Requesting the same name again should give the same value.
386 SequencedWorkerPool::SequenceToken token1again = 426 SequencedWorkerPool::SequenceToken token1again =
387 pool()->GetNamedSequenceToken(name1); 427 pool()->GetNamedSequenceToken(name1);
388 EXPECT_TRUE(token1.Equals(token1again)); 428 EXPECT_TRUE(token1.Equals(token1again));
389 429
390 SequencedWorkerPool::SequenceToken token3again = 430 SequencedWorkerPool::SequenceToken token3again =
391 pool()->GetNamedSequenceToken(name3); 431 pool()->GetNamedSequenceToken(name3);
392 EXPECT_TRUE(token3.Equals(token3again)); 432 EXPECT_TRUE(token3.Equals(token3again));
393 } 433 }
394 434
395 // Tests that posting a bunch of tasks (many more than the number of worker 435 // Tests that posting a bunch of tasks (many more than the number of worker
396 // threads) runs them all. 436 // threads) runs them all.
397 TEST_F(SequencedWorkerPoolTest, LotsOfTasks) { 437 TEST_P(SequencedWorkerPoolTest, LotsOfTasks) {
398 pool()->PostWorkerTask(FROM_HERE, 438 pool()->PostWorkerTask(FROM_HERE,
399 base::Bind(&TestTracker::SlowTask, tracker(), 0)); 439 base::Bind(&TestTracker::SlowTask, tracker(), 0));
400 440
401 const size_t kNumTasks = 20; 441 const size_t kNumTasks = 20;
402 for (size_t i = 1; i < kNumTasks; i++) { 442 for (size_t i = 1; i < kNumTasks; i++) {
403 pool()->PostWorkerTask(FROM_HERE, 443 pool()->PostWorkerTask(FROM_HERE,
404 base::Bind(&TestTracker::FastTask, tracker(), i)); 444 base::Bind(&TestTracker::FastTask, tracker(), i));
405 } 445 }
406 446
407 std::vector<int> result = tracker()->WaitUntilTasksComplete(kNumTasks); 447 std::vector<int> result = tracker()->WaitUntilTasksComplete(kNumTasks);
408 EXPECT_EQ(kNumTasks, result.size()); 448 EXPECT_EQ(kNumTasks, result.size());
409 } 449 }
410 450
411 // Tests that posting a bunch of tasks (many more than the number of 451 // Tests that posting a bunch of tasks (many more than the number of
412 // worker threads) to two pools simultaneously runs them all twice. 452 // worker threads) to two pools simultaneously runs them all twice.
413 // This test is meant to shake out any concurrency issues between 453 // This test is meant to shake out any concurrency issues between
414 // pools (like histograms). 454 // pools (like histograms).
415 TEST_F(SequencedWorkerPoolTest, LotsOfTasksTwoPools) { 455 TEST_P(SequencedWorkerPoolTest, LotsOfTasksTwoPools) {
416 SequencedWorkerPoolOwner pool1(kNumWorkerThreads, "test1"); 456 SequencedWorkerPoolOwner pool1(kNumWorkerThreads, "test1");
417 SequencedWorkerPoolOwner pool2(kNumWorkerThreads, "test2"); 457 SequencedWorkerPoolOwner pool2(kNumWorkerThreads, "test2");
418 458
419 base::Closure slow_task = base::Bind(&TestTracker::SlowTask, tracker(), 0); 459 base::Closure slow_task = base::Bind(&TestTracker::SlowTask, tracker(), 0);
420 pool1.pool()->PostWorkerTask(FROM_HERE, slow_task); 460 pool1.pool()->PostWorkerTask(FROM_HERE, slow_task);
421 pool2.pool()->PostWorkerTask(FROM_HERE, slow_task); 461 pool2.pool()->PostWorkerTask(FROM_HERE, slow_task);
422 462
423 const size_t kNumTasks = 20; 463 const size_t kNumTasks = 20;
424 for (size_t i = 1; i < kNumTasks; i++) { 464 for (size_t i = 1; i < kNumTasks; i++) {
425 base::Closure fast_task = 465 base::Closure fast_task =
426 base::Bind(&TestTracker::FastTask, tracker(), i); 466 base::Bind(&TestTracker::FastTask, tracker(), i);
427 pool1.pool()->PostWorkerTask(FROM_HERE, fast_task); 467 pool1.pool()->PostWorkerTask(FROM_HERE, fast_task);
428 pool2.pool()->PostWorkerTask(FROM_HERE, fast_task); 468 pool2.pool()->PostWorkerTask(FROM_HERE, fast_task);
429 } 469 }
430 470
431 std::vector<int> result = 471 std::vector<int> result =
432 tracker()->WaitUntilTasksComplete(2*kNumTasks); 472 tracker()->WaitUntilTasksComplete(2*kNumTasks);
433 EXPECT_EQ(2 * kNumTasks, result.size()); 473 EXPECT_EQ(2 * kNumTasks, result.size());
434 } 474 }
435 475
436 // Test that tasks with the same sequence token are executed in order but don't 476 // Test that tasks with the same sequence token are executed in order but don't
437 // affect other tasks. 477 // affect other tasks.
438 TEST_F(SequencedWorkerPoolTest, Sequence) { 478 TEST_P(SequencedWorkerPoolTest, Sequence) {
439 // Fill all the worker threads except one. 479 // Fill all the worker threads except one.
440 const size_t kNumBackgroundTasks = kNumWorkerThreads - 1; 480 const size_t kNumBackgroundTasks = kNumWorkerThreads - 1;
441 ThreadBlocker background_blocker; 481 ThreadBlocker background_blocker;
442 for (size_t i = 0; i < kNumBackgroundTasks; i++) { 482 for (size_t i = 0; i < kNumBackgroundTasks; i++) {
443 pool()->PostWorkerTask(FROM_HERE, 483 pool()->PostWorkerTask(FROM_HERE,
444 base::Bind(&TestTracker::BlockTask, 484 base::Bind(&TestTracker::BlockTask,
445 tracker(), i, &background_blocker)); 485 tracker(), i, &background_blocker));
446 } 486 }
447 tracker()->WaitUntilTasksBlocked(kNumBackgroundTasks); 487 tracker()->WaitUntilTasksBlocked(kNumBackgroundTasks);
448 488
(...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. 529 // Allow the first task of token1 to complete. This should run the second.
490 blocker.Unblock(1); 530 blocker.Unblock(1);
491 result = tracker()->WaitUntilTasksComplete(kNumBackgroundTasks + 4); 531 result = tracker()->WaitUntilTasksComplete(kNumBackgroundTasks + 4);
492 ASSERT_EQ(kNumBackgroundTasks + 4, result.size()); 532 ASSERT_EQ(kNumBackgroundTasks + 4, result.size());
493 EXPECT_EQ(100, result[result.size() - 2]); 533 EXPECT_EQ(100, result[result.size() - 2]);
494 EXPECT_EQ(101, result[result.size() - 1]); 534 EXPECT_EQ(101, result[result.size() - 1]);
495 } 535 }
496 536
497 // Tests that any tasks posted after Shutdown are ignored. 537 // Tests that any tasks posted after Shutdown are ignored.
498 // Disabled for flakiness. See http://crbug.com/166451. 538 // Disabled for flakiness. See http://crbug.com/166451.
499 TEST_F(SequencedWorkerPoolTest, DISABLED_IgnoresAfterShutdown) { 539 TEST_P(SequencedWorkerPoolTest, DISABLED_IgnoresAfterShutdown) {
500 // Start tasks to take all the threads and block them. 540 // Start tasks to take all the threads and block them.
501 EnsureAllWorkersCreated(); 541 EnsureAllWorkersCreated();
502 ThreadBlocker blocker; 542 ThreadBlocker blocker;
503 for (size_t i = 0; i < kNumWorkerThreads; i++) { 543 for (size_t i = 0; i < kNumWorkerThreads; i++) {
504 pool()->PostWorkerTask(FROM_HERE, 544 pool()->PostWorkerTask(FROM_HERE,
505 base::Bind(&TestTracker::BlockTask, 545 base::Bind(&TestTracker::BlockTask,
506 tracker(), i, &blocker)); 546 tracker(), i, &blocker));
507 } 547 }
508 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); 548 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads);
509 549
(...skipping 26 matching lines...) Expand all
536 base::Bind(&TestTracker::FastTask, tracker(), 101), 576 base::Bind(&TestTracker::FastTask, tracker(), 101),
537 SequencedWorkerPool::SKIP_ON_SHUTDOWN)); 577 SequencedWorkerPool::SKIP_ON_SHUTDOWN));
538 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior( 578 EXPECT_FALSE(pool()->PostWorkerTaskWithShutdownBehavior(
539 FROM_HERE, 579 FROM_HERE,
540 base::Bind(&TestTracker::FastTask, tracker(), 102), 580 base::Bind(&TestTracker::FastTask, tracker(), 102),
541 SequencedWorkerPool::BLOCK_SHUTDOWN)); 581 SequencedWorkerPool::BLOCK_SHUTDOWN));
542 582
543 ASSERT_EQ(old_has_work_call_count, has_work_call_count()); 583 ASSERT_EQ(old_has_work_call_count, has_work_call_count());
544 } 584 }
545 585
546 TEST_F(SequencedWorkerPoolTest, AllowsAfterShutdown) { 586 TEST_P(SequencedWorkerPoolTest, AllowsAfterShutdown) {
587 // As tested by TaskSchedulerTaskTrackerTest.WillPostAndRunDuringShutdown,
588 // TaskScheduler allows tasks to be posted during shutdown. However, since it
589 // doesn't provide a way to run a callback from inside its Shutdown() method,
590 // it would be hard to make this test work with redirection enabled.
591 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
592 return;
593
547 // Test that <n> new blocking tasks are allowed provided they're posted 594 // Test that <n> new blocking tasks are allowed provided they're posted
548 // by a running tasks. 595 // by a running tasks.
549 EnsureAllWorkersCreated(); 596 EnsureAllWorkersCreated();
550 ThreadBlocker blocker; 597 ThreadBlocker blocker;
551 598
552 // Start tasks to take all the threads and block them. 599 // Start tasks to take all the threads and block them.
553 const int kNumBlockTasks = static_cast<int>(kNumWorkerThreads); 600 const int kNumBlockTasks = static_cast<int>(kNumWorkerThreads);
554 for (int i = 0; i < kNumBlockTasks; ++i) { 601 for (int i = 0; i < kNumBlockTasks; ++i) {
555 EXPECT_TRUE(pool()->PostWorkerTask( 602 EXPECT_TRUE(pool()->PostWorkerTask(
556 FROM_HERE, 603 FROM_HERE,
(...skipping 25 matching lines...) Expand all
582 // Ensure that the correct number of tasks actually got run. 629 // Ensure that the correct number of tasks actually got run.
583 tracker()->WaitUntilTasksComplete(static_cast<size_t>( 630 tracker()->WaitUntilTasksComplete(static_cast<size_t>(
584 kNumBlockTasks + kNumQueuedTasks + kNumNewBlockingTasksToAllow)); 631 kNumBlockTasks + kNumQueuedTasks + kNumNewBlockingTasksToAllow));
585 632
586 // Clean up the task IDs we added and go home. 633 // Clean up the task IDs we added and go home.
587 tracker()->ClearCompleteSequence(); 634 tracker()->ClearCompleteSequence();
588 } 635 }
589 636
590 // Tests that blocking tasks can still be posted during shutdown, as long as 637 // 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. 638 // the task is not being posted within the context of a running task.
592 TEST_F(SequencedWorkerPoolTest, 639 TEST_P(SequencedWorkerPoolTest,
593 AllowsBlockingTasksDuringShutdownOutsideOfRunningTask) { 640 AllowsBlockingTasksDuringShutdownOutsideOfRunningTask) {
641 // As tested by TaskSchedulerTaskTrackerTest.WillPostAndRunDuringShutdown,
642 // TaskScheduler allows tasks to be posted during shutdown. However, since it
643 // doesn't provide a way to run a callback from inside its Shutdown() method,
644 // it would be hard to make this test work with redirection enabled.
645 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
646 return;
647
594 EnsureAllWorkersCreated(); 648 EnsureAllWorkersCreated();
595 ThreadBlocker blocker; 649 ThreadBlocker blocker;
596 650
597 // Start tasks to take all the threads and block them. 651 // Start tasks to take all the threads and block them.
598 const int kNumBlockTasks = static_cast<int>(kNumWorkerThreads); 652 const int kNumBlockTasks = static_cast<int>(kNumWorkerThreads);
599 for (int i = 0; i < kNumBlockTasks; ++i) { 653 for (int i = 0; i < kNumBlockTasks; ++i) {
600 EXPECT_TRUE(pool()->PostWorkerTask( 654 EXPECT_TRUE(pool()->PostWorkerTask(
601 FROM_HERE, 655 FROM_HERE,
602 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker))); 656 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker)));
603 } 657 }
604 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads); 658 tracker()->WaitUntilTasksBlocked(kNumWorkerThreads);
605 659
606 // Setup to open the floodgates from within Shutdown(). 660 // Setup to open the floodgates from within Shutdown().
607 SetWillWaitForShutdownCallback( 661 SetWillWaitForShutdownCallback(
608 base::Bind(&TestTracker::PostBlockingTaskThenUnblockThreads, 662 base::Bind(&TestTracker::PostBlockingTaskThenUnblockThreads,
609 scoped_refptr<TestTracker>(tracker()), pool(), &blocker, 663 scoped_refptr<TestTracker>(tracker()), pool(), &blocker,
610 kNumWorkerThreads)); 664 kNumWorkerThreads));
611 pool()->Shutdown(kNumWorkerThreads + 1); 665 pool()->Shutdown(kNumWorkerThreads + 1);
612 666
613 // Ensure that the correct number of tasks actually got run. 667 // Ensure that the correct number of tasks actually got run.
614 tracker()->WaitUntilTasksComplete(static_cast<size_t>(kNumWorkerThreads + 1)); 668 tracker()->WaitUntilTasksComplete(static_cast<size_t>(kNumWorkerThreads + 1));
615 tracker()->ClearCompleteSequence(); 669 tracker()->ClearCompleteSequence();
616 } 670 }
617 671
618 // Tests that unrun tasks are discarded properly according to their shutdown 672 // Tests that unrun tasks are discarded properly according to their shutdown
619 // mode. 673 // mode.
620 TEST_F(SequencedWorkerPoolTest, DiscardOnShutdown) { 674 TEST_P(SequencedWorkerPoolTest, DiscardOnShutdown) {
675 // As tested by
676 // TaskSchedulerTaskTrackerTest.WillPostBeforeShutdownRunDuringShutdown, on
677 // shutdown, the TaskScheduler discards SKIP_ON_SHUTDOWN and
678 // CONTINUE_ON_SHUTDOWN tasks and runs BLOCK_SHUTDOWN tasks. However, since it
679 // doesn't provide a way to run a callback from inside its Shutdown() method,
680 // it would be hard to make this test work with redirection 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();
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 // As tested by
779 // TaskSchedulerTaskTrackerTest.WillPostAndRunLongTaskBeforeShutdown and
780 // TaskSchedulerTaskTrackerTest.WillPostBeforeShutdownRunDuringShutdown, the
781 // TaskScheduler correctly handles SKIP_ON_SHUTDOWN tasks. However, since it
782 // doesn't provide a way to run a callback from inside its Shutdown() method,
783 // it would be hard to make this test work with redirection enabled.
784 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
785 return;
786
713 // Start tasks to take all the threads and block them. 787 // Start tasks to take all the threads and block them.
714 EnsureAllWorkersCreated(); 788 EnsureAllWorkersCreated();
715 ThreadBlocker blocker; 789 ThreadBlocker blocker;
716 790
717 // Now block all the threads with SKIP_ON_SHUTDOWN. Shutdown() should not 791 // Now block all the threads with SKIP_ON_SHUTDOWN. Shutdown() should not
718 // return until these tasks have completed. 792 // return until these tasks have completed.
719 for (size_t i = 0; i < kNumWorkerThreads; i++) { 793 for (size_t i = 0; i < kNumWorkerThreads; i++) {
720 pool()->PostWorkerTaskWithShutdownBehavior( 794 pool()->PostWorkerTaskWithShutdownBehavior(
721 FROM_HERE, 795 FROM_HERE,
722 base::Bind(&TestTracker::BlockTask, tracker(), i, &blocker), 796 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 827 // allowed to complete. No additional non-blocking tasks should have been
754 // started. 828 // started.
755 ASSERT_EQ(kNumWorkerThreads, result.size()); 829 ASSERT_EQ(kNumWorkerThreads, result.size());
756 for (size_t i = 0; i < kNumWorkerThreads; i++) 830 for (size_t i = 0; i < kNumWorkerThreads; i++)
757 EXPECT_TRUE(ContainsValue(result, static_cast<int>(i))); 831 EXPECT_TRUE(ContainsValue(result, static_cast<int>(i)));
758 } 832 }
759 833
760 // Ensure all worker threads are created, and then trigger a spurious 834 // Ensure all worker threads are created, and then trigger a spurious
761 // work signal. This shouldn't cause any other work signals to be 835 // work signal. This shouldn't cause any other work signals to be
762 // triggered. This is a regression test for http://crbug.com/117469. 836 // triggered. This is a regression test for http://crbug.com/117469.
763 TEST_F(SequencedWorkerPoolTest, SpuriousWorkSignal) { 837 TEST_P(SequencedWorkerPoolTest, SpuriousWorkSignal) {
838 // This test doesn't apply when tasks are redirected to the TaskScheduler.
839 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
840 return;
841
764 EnsureAllWorkersCreated(); 842 EnsureAllWorkersCreated();
765 int old_has_work_call_count = has_work_call_count(); 843 int old_has_work_call_count = has_work_call_count();
766 pool()->SignalHasWorkForTesting(); 844 pool()->SignalHasWorkForTesting();
767 // This is inherently racy, but can only produce false positives. 845 // This is inherently racy, but can only produce false positives.
768 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); 846 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100));
769 EXPECT_EQ(old_has_work_call_count + 1, has_work_call_count()); 847 EXPECT_EQ(old_has_work_call_count + 1, has_work_call_count());
770 } 848 }
771 849
772 void VerifyRunsTasksOnCurrentThread( 850 void VerifyRunsTasksOnCurrentThread(
851 SequencedWorkerPoolRedirection redirection,
773 scoped_refptr<TaskRunner> test_positive_task_runner, 852 scoped_refptr<TaskRunner> test_positive_task_runner,
774 scoped_refptr<TaskRunner> test_negative_task_runner, 853 scoped_refptr<TaskRunner> test_negative_task_runner,
775 SequencedWorkerPool* pool, 854 SequencedWorkerPool* pool,
776 SequencedWorkerPool* unused_pool) { 855 SequencedWorkerPool* unused_pool) {
777 EXPECT_TRUE(test_positive_task_runner->RunsTasksOnCurrentThread()); 856 EXPECT_TRUE(test_positive_task_runner->RunsTasksOnCurrentThread());
778 EXPECT_FALSE(test_negative_task_runner->RunsTasksOnCurrentThread()); 857 EXPECT_FALSE(test_negative_task_runner->RunsTasksOnCurrentThread());
779 EXPECT_TRUE(pool->RunsTasksOnCurrentThread()); 858 EXPECT_TRUE(pool->RunsTasksOnCurrentThread());
780 EXPECT_FALSE(unused_pool->RunsTasksOnCurrentThread()); 859
860 // Tasks posted to different SequencedWorkerPools may run on the same
861 // TaskScheduler threads.
862 if (redirection == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
863 EXPECT_TRUE(unused_pool->RunsTasksOnCurrentThread());
864 else
865 EXPECT_FALSE(unused_pool->RunsTasksOnCurrentThread());
781 } 866 }
782 867
783 // Verify correctness of the RunsTasksOnCurrentThread() method on 868 // Verify correctness of the RunsTasksOnCurrentThread() method on
784 // SequencedWorkerPool and on TaskRunners it returns. 869 // SequencedWorkerPool and on TaskRunners it returns.
785 TEST_F(SequencedWorkerPoolTest, RunsTasksOnCurrentThread) { 870 TEST_P(SequencedWorkerPoolTest, RunsTasksOnCurrentThread) {
786 const scoped_refptr<SequencedTaskRunner> sequenced_task_runner_1 = 871 const scoped_refptr<SequencedTaskRunner> sequenced_task_runner_1 =
787 pool()->GetSequencedTaskRunner(SequencedWorkerPool::GetSequenceToken()); 872 pool()->GetSequencedTaskRunner(SequencedWorkerPool::GetSequenceToken());
788 const scoped_refptr<SequencedTaskRunner> sequenced_task_runner_2 = 873 const scoped_refptr<SequencedTaskRunner> sequenced_task_runner_2 =
789 pool()->GetSequencedTaskRunner(SequencedWorkerPool::GetSequenceToken()); 874 pool()->GetSequencedTaskRunner(SequencedWorkerPool::GetSequenceToken());
790 const scoped_refptr<TaskRunner> unsequenced_task_runner = 875 const scoped_refptr<TaskRunner> unsequenced_task_runner =
791 pool()->GetTaskRunnerWithShutdownBehavior( 876 pool()->GetTaskRunnerWithShutdownBehavior(
792 SequencedWorkerPool::BLOCK_SHUTDOWN); 877 SequencedWorkerPool::BLOCK_SHUTDOWN);
793 878
794 SequencedWorkerPoolOwner unused_pool_owner(2, "unused_pool"); 879 SequencedWorkerPoolOwner unused_pool_owner(2, "unused_pool");
795 880
796 EXPECT_FALSE(pool()->RunsTasksOnCurrentThread()); 881 EXPECT_FALSE(pool()->RunsTasksOnCurrentThread());
797 EXPECT_FALSE(sequenced_task_runner_1->RunsTasksOnCurrentThread()); 882 EXPECT_FALSE(sequenced_task_runner_1->RunsTasksOnCurrentThread());
798 EXPECT_FALSE(sequenced_task_runner_2->RunsTasksOnCurrentThread()); 883 EXPECT_FALSE(sequenced_task_runner_2->RunsTasksOnCurrentThread());
799 EXPECT_FALSE(unsequenced_task_runner->RunsTasksOnCurrentThread()); 884 EXPECT_FALSE(unsequenced_task_runner->RunsTasksOnCurrentThread());
800 EXPECT_FALSE(unused_pool_owner.pool()->RunsTasksOnCurrentThread()); 885 EXPECT_FALSE(unused_pool_owner.pool()->RunsTasksOnCurrentThread());
801 886
802 // From a task posted to |sequenced_task_runner_1|: 887 // From a task posted to |sequenced_task_runner_1|:
803 // - sequenced_task_runner_1->RunsTasksOnCurrentThread() returns true. 888 // - sequenced_task_runner_1->RunsTasksOnCurrentThread() returns true.
804 // - sequenced_task_runner_2->RunsTasksOnCurrentThread() returns false. 889 // - sequenced_task_runner_2->RunsTasksOnCurrentThread() returns false.
805 // - pool()->RunsTasksOnCurrentThread() returns true. 890 // - pool()->RunsTasksOnCurrentThread() returns true.
806 // - unused_pool_owner.pool()->RunsTasksOnCurrentThread() returns false. 891 // - unused_pool_owner.pool()->RunsTasksOnCurrentThread() returns false.
807 sequenced_task_runner_1->PostTask( 892 sequenced_task_runner_1->PostTask(
808 FROM_HERE, 893 FROM_HERE, base::Bind(&VerifyRunsTasksOnCurrentThread, GetParam(),
809 base::Bind(&VerifyRunsTasksOnCurrentThread, sequenced_task_runner_1, 894 sequenced_task_runner_1, sequenced_task_runner_2,
810 sequenced_task_runner_2, base::RetainedRef(pool()), 895 base::RetainedRef(pool()),
811 base::RetainedRef(unused_pool_owner.pool()))); 896 base::RetainedRef(unused_pool_owner.pool())));
812 // From a task posted to |unsequenced_task_runner|: 897 // From a task posted to |unsequenced_task_runner|:
813 // - unsequenced_task_runner->RunsTasksOnCurrentThread() returns true. 898 // - unsequenced_task_runner->RunsTasksOnCurrentThread() returns true.
814 // - sequenced_task_runner_1->RunsTasksOnCurrentThread() returns false. 899 // - sequenced_task_runner_1->RunsTasksOnCurrentThread() returns false.
815 // - pool()->RunsTasksOnCurrentThread() returns true. 900 // - pool()->RunsTasksOnCurrentThread() returns true.
816 // - unused_pool_owner.pool()->RunsTasksOnCurrentThread() returns false. 901 // - unused_pool_owner.pool()->RunsTasksOnCurrentThread() returns false.
817 unsequenced_task_runner->PostTask( 902 unsequenced_task_runner->PostTask(
818 FROM_HERE, 903 FROM_HERE, base::Bind(&VerifyRunsTasksOnCurrentThread, GetParam(),
819 base::Bind(&VerifyRunsTasksOnCurrentThread, unsequenced_task_runner, 904 unsequenced_task_runner, sequenced_task_runner_1,
820 sequenced_task_runner_1, base::RetainedRef(pool()), 905 base::RetainedRef(pool()),
821 base::RetainedRef(unused_pool_owner.pool()))); 906 base::RetainedRef(unused_pool_owner.pool())));
822 } 907 }
823 908
824 // Checks that tasks are destroyed in the right context during shutdown. If a 909 // Checks that tasks are destroyed in the right context during shutdown. If a
825 // task is destroyed while SequencedWorkerPool's global lock is held, 910 // task is destroyed while SequencedWorkerPool's global lock is held,
826 // SequencedWorkerPool might deadlock. 911 // SequencedWorkerPool might deadlock.
827 TEST_F(SequencedWorkerPoolTest, AvoidsDeadlockOnShutdown) { 912 TEST_P(SequencedWorkerPoolTest, AvoidsDeadlockOnShutdown) {
913 // Note: The TaskScheduler does not destroy tasks on shutdown.
gab 2016/09/16 20:16:10 Why does it pass in redirection then?! Are the Des
fdoray 2016/09/16 21:21:31 DestructionDeadlockChecker verifies that using the
914
828 for (int i = 0; i < 4; ++i) { 915 for (int i = 0; i < 4; ++i) {
829 scoped_refptr<DestructionDeadlockChecker> checker( 916 scoped_refptr<DestructionDeadlockChecker> checker(
830 new DestructionDeadlockChecker(pool())); 917 new DestructionDeadlockChecker(pool()));
831 tracker()->PostRepostingTask(pool(), checker); 918 tracker()->PostRepostingTask(pool(), checker);
832 } 919 }
833 920
834 // Shutting down the pool should destroy the DestructionDeadlockCheckers, 921 // Shutting down the pool should destroy the DestructionDeadlockCheckers,
835 // which in turn should not deadlock in their destructors. 922 // which in turn should not deadlock in their destructors.
836 pool()->Shutdown(); 923 pool()->Shutdown();
837 } 924 }
838 925
839 // Similar to the test AvoidsDeadlockOnShutdown, but there are now also 926 // Similar to the test AvoidsDeadlockOnShutdown, but there are now also
840 // sequenced, blocking tasks in the queue during shutdown. 927 // sequenced, blocking tasks in the queue during shutdown.
841 TEST_F(SequencedWorkerPoolTest, 928 TEST_P(SequencedWorkerPoolTest,
842 AvoidsDeadlockOnShutdownWithSequencedBlockingTasks) { 929 AvoidsDeadlockOnShutdownWithSequencedBlockingTasks) {
930 // This test can't run when tasks are redirected to TaskScheduler because it
931 // doesn't provide a way to limit the number of BLOCK_SHUTDOWN tasks posted
932 // during shutdown.
gab 2016/09/16 20:16:10 I don't understand what this test has to do with t
fdoray 2016/09/16 21:21:31 Clarified the comment.
933 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
934 return;
935
843 const std::string sequence_token_name("name"); 936 const std::string sequence_token_name("name");
844 for (int i = 0; i < 4; ++i) { 937 for (int i = 0; i < 4; ++i) {
845 scoped_refptr<DestructionDeadlockChecker> checker( 938 scoped_refptr<DestructionDeadlockChecker> checker(
846 new DestructionDeadlockChecker(pool())); 939 new DestructionDeadlockChecker(pool()));
847 tracker()->PostRepostingTask(pool(), checker); 940 tracker()->PostRepostingTask(pool(), checker);
848 941
849 SequencedWorkerPool::SequenceToken token1 = 942 SequencedWorkerPool::SequenceToken token1 =
850 pool()->GetNamedSequenceToken(sequence_token_name); 943 pool()->GetNamedSequenceToken(sequence_token_name);
851 tracker()->PostRepostingBlockingTask(pool(), token1); 944 tracker()->PostRepostingBlockingTask(pool(), token1);
852 } 945 }
853 946
854 // Shutting down the pool should destroy the DestructionDeadlockCheckers, 947 // Shutting down the pool should destroy the DestructionDeadlockCheckers,
855 // which in turn should not deadlock in their destructors. 948 // which in turn should not deadlock in their destructors.
856 pool()->Shutdown(); 949 pool()->Shutdown();
857 } 950 }
858 951
859 // Verify that FlushForTesting works as intended. 952 // Verify that FlushForTesting works as intended.
860 TEST_F(SequencedWorkerPoolTest, FlushForTesting) { 953 TEST_P(SequencedWorkerPoolTest, FlushForTesting) {
954 // FlushForTesting() can't be called when tasks are redirected to the
955 // TaskScheduler.
956 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
957 return;
958
861 // Should be fine to call on a new instance. 959 // Should be fine to call on a new instance.
862 pool()->FlushForTesting(); 960 pool()->FlushForTesting();
863 961
864 // Queue up a bunch of work, including a long delayed task and 962 // Queue up a bunch of work, including a long delayed task and
865 // a task that produces additional tasks as an artifact. 963 // a task that produces additional tasks as an artifact.
866 pool()->PostDelayedWorkerTask( 964 pool()->PostDelayedWorkerTask(
867 FROM_HERE, 965 FROM_HERE,
868 base::Bind(&TestTracker::FastTask, tracker(), 0), 966 base::Bind(&TestTracker::FastTask, tracker(), 0),
869 TimeDelta::FromMinutes(5)); 967 TimeDelta::FromMinutes(5));
870 pool()->PostWorkerTask(FROM_HERE, 968 pool()->PostWorkerTask(FROM_HERE,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 SequencedWorkerPool::GetSequenceTokenForCurrentThread(); 1003 SequencedWorkerPool::GetSequenceTokenForCurrentThread();
906 EXPECT_EQ(expected_token.ToString(), token.ToString()); 1004 EXPECT_EQ(expected_token.ToString(), token.ToString());
907 1005
908 scoped_refptr<SequencedWorkerPool> pool = 1006 scoped_refptr<SequencedWorkerPool> pool =
909 SequencedWorkerPool::GetWorkerPoolForCurrentThread(); 1007 SequencedWorkerPool::GetWorkerPoolForCurrentThread();
910 EXPECT_EQ(expected_pool, pool); 1008 EXPECT_EQ(expected_pool, pool);
911 } 1009 }
912 1010
913 } // namespace 1011 } // namespace
914 1012
915 TEST_F(SequencedWorkerPoolTest, GetWorkerPoolAndSequenceTokenForCurrentThread) { 1013 TEST_P(SequencedWorkerPoolTest, GetWorkerPoolAndSequenceTokenForCurrentThread) {
1014 // GetSequenceTokenForCurrentThread() and GetWorkerPoolForCurrentThread()
1015 // respectively return an invalid token and nullptr from a task posted to a
1016 // SequencedWorkerPool when redirection to TaskScheduler is enabled. These
1017 // methods are only used from SequencedTaskRunnerHandle and
1018 // SequenceCheckerImpl which work fine in TaskScheduler.
1019 if (GetParam() == SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER)
1020 return;
1021
916 EnsureAllWorkersCreated(); 1022 EnsureAllWorkersCreated();
917 1023
918 // The current thread should have neither a worker pool nor a sequence token. 1024 // The current thread should have neither a worker pool nor a sequence token.
919 SequencedWorkerPool::SequenceToken local_token = 1025 SequencedWorkerPool::SequenceToken local_token =
920 SequencedWorkerPool::GetSequenceTokenForCurrentThread(); 1026 SequencedWorkerPool::GetSequenceTokenForCurrentThread();
921 scoped_refptr<SequencedWorkerPool> local_pool = 1027 scoped_refptr<SequencedWorkerPool> local_pool =
922 SequencedWorkerPool::GetWorkerPoolForCurrentThread(); 1028 SequencedWorkerPool::GetWorkerPoolForCurrentThread();
923 EXPECT_FALSE(local_token.IsValid()) << local_token.ToString(); 1029 EXPECT_FALSE(local_token.IsValid()) << local_token.ToString();
924 EXPECT_FALSE(local_pool); 1030 EXPECT_FALSE(local_pool);
925 1031
926 SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken(); 1032 SequencedWorkerPool::SequenceToken token1 = pool()->GetSequenceToken();
927 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken(); 1033 SequencedWorkerPool::SequenceToken token2 = pool()->GetSequenceToken();
928 pool()->PostSequencedWorkerTask( 1034 pool()->PostSequencedWorkerTask(
929 token1, FROM_HERE, 1035 token1, FROM_HERE,
930 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token1)); 1036 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token1));
931 pool()->PostSequencedWorkerTask( 1037 pool()->PostSequencedWorkerTask(
932 token2, FROM_HERE, 1038 token2, FROM_HERE,
933 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token2)); 1039 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), token2));
934 1040
935 pool()->PostWorkerTask(FROM_HERE, 1041 pool()->PostWorkerTask(FROM_HERE,
936 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(), 1042 base::Bind(&CheckWorkerPoolAndSequenceToken, pool(),
937 SequencedWorkerPool::SequenceToken())); 1043 SequencedWorkerPool::SequenceToken()));
938 1044
939 pool()->FlushForTesting(); 1045 pool()->FlushForTesting();
940 } 1046 }
941 1047
942 TEST_F(SequencedWorkerPoolTest, ShutsDownCleanWithContinueOnShutdown) { 1048 TEST_P(SequencedWorkerPoolTest, ShutsDownCleanWithContinueOnShutdown) {
943 scoped_refptr<SequencedTaskRunner> task_runner = 1049 scoped_refptr<SequencedTaskRunner> task_runner =
944 pool()->GetSequencedTaskRunnerWithShutdownBehavior( 1050 pool()->GetSequencedTaskRunnerWithShutdownBehavior(
945 pool()->GetSequenceToken(), 1051 pool()->GetSequenceToken(),
946 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); 1052 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
947 1053
948 // Upon test exit, should shut down without hanging. 1054 // Upon test exit, should shut down without hanging.
949 pool()->Shutdown(); 1055 pool()->Shutdown();
950 } 1056 }
951 1057
1058 INSTANTIATE_TEST_CASE_P(
1059 NoRedirection,
1060 SequencedWorkerPoolTest,
1061 ::testing::Values(SequencedWorkerPoolRedirection::NONE));
1062 INSTANTIATE_TEST_CASE_P(
1063 RedirectionToTaskScheduler,
1064 SequencedWorkerPoolTest,
1065 ::testing::Values(SequencedWorkerPoolRedirection::TO_TASK_SCHEDULER));
1066
952 class SequencedWorkerPoolTaskRunnerTestDelegate { 1067 class SequencedWorkerPoolTaskRunnerTestDelegate {
953 public: 1068 public:
954 SequencedWorkerPoolTaskRunnerTestDelegate() {} 1069 SequencedWorkerPoolTaskRunnerTestDelegate() {}
955 1070
956 ~SequencedWorkerPoolTaskRunnerTestDelegate() {} 1071 ~SequencedWorkerPoolTaskRunnerTestDelegate() {}
957 1072
958 void StartTaskRunner() { 1073 void StartTaskRunner() {
959 pool_owner_.reset( 1074 pool_owner_.reset(
960 new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest")); 1075 new SequencedWorkerPoolOwner(10, "SequencedWorkerPoolTaskRunnerTest"));
961 } 1076 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest, 1183 SequencedWorkerPoolSequencedTaskRunner, SequencedTaskRunnerTest,
1069 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); 1184 SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
1070 INSTANTIATE_TYPED_TEST_CASE_P( 1185 INSTANTIATE_TYPED_TEST_CASE_P(
1071 SequencedWorkerPoolSequencedTaskRunner, 1186 SequencedWorkerPoolSequencedTaskRunner,
1072 SequencedTaskRunnerDelayedTest, 1187 SequencedTaskRunnerDelayedTest,
1073 SequencedWorkerPoolSequencedTaskRunnerTestDelegate); 1188 SequencedWorkerPoolSequencedTaskRunnerTestDelegate);
1074 1189
1075 } // namespace 1190 } // namespace
1076 1191
1077 } // namespace base 1192 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698