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

Side by Side Diff: base/task_scheduler/scheduler_worker_unittest.cc

Issue 2692863012: SchedulerWorker Refcounting for Destruction in Production (Closed)
Patch Set: CR Feedback Created 3 years, 10 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/task_scheduler/scheduler_worker.h" 5 #include "base/task_scheduler/scheduler_worker.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/bind_helpers.h" 13 #include "base/bind_helpers.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
16 #include "base/memory/ref_counted.h"
16 #include "base/synchronization/condition_variable.h" 17 #include "base/synchronization/condition_variable.h"
17 #include "base/synchronization/waitable_event.h" 18 #include "base/synchronization/waitable_event.h"
18 #include "base/task_scheduler/scheduler_lock.h" 19 #include "base/task_scheduler/scheduler_lock.h"
19 #include "base/task_scheduler/sequence.h" 20 #include "base/task_scheduler/sequence.h"
20 #include "base/task_scheduler/task.h" 21 #include "base/task_scheduler/task.h"
21 #include "base/task_scheduler/task_tracker.h" 22 #include "base/task_scheduler/task_tracker.h"
23 #include "base/test/test_timeouts.h"
22 #include "base/threading/platform_thread.h" 24 #include "base/threading/platform_thread.h"
25 #include "base/threading/simple_thread.h"
23 #include "base/time/time.h" 26 #include "base/time/time.h"
24 #include "build/build_config.h" 27 #include "build/build_config.h"
25 #include "testing/gmock/include/gmock/gmock.h" 28 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h" 29 #include "testing/gtest/include/gtest/gtest.h"
27 30
28 #if defined(OS_WIN) 31 #if defined(OS_WIN)
29 #include <objbase.h> 32 #include <objbase.h>
30 #endif 33 #endif
31 34
32 using testing::_; 35 using testing::_;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 std::vector<scoped_refptr<Sequence>> CreatedSequences() { 117 std::vector<scoped_refptr<Sequence>> CreatedSequences() {
115 AutoSchedulerLock auto_lock(lock_); 118 AutoSchedulerLock auto_lock(lock_);
116 return created_sequences_; 119 return created_sequences_;
117 } 120 }
118 121
119 std::vector<scoped_refptr<Sequence>> EnqueuedSequences() { 122 std::vector<scoped_refptr<Sequence>> EnqueuedSequences() {
120 AutoSchedulerLock auto_lock(lock_); 123 AutoSchedulerLock auto_lock(lock_);
121 return re_enqueued_sequences_; 124 return re_enqueued_sequences_;
122 } 125 }
123 126
124 std::unique_ptr<SchedulerWorker> worker_; 127 scoped_refptr<SchedulerWorker> worker_;
125 128
126 private: 129 private:
127 class TestSchedulerWorkerDelegate : public SchedulerWorkerDefaultDelegate { 130 class TestSchedulerWorkerDelegate : public SchedulerWorkerDefaultDelegate {
128 public: 131 public:
129 TestSchedulerWorkerDelegate(TaskSchedulerWorkerTest* outer) 132 TestSchedulerWorkerDelegate(TaskSchedulerWorkerTest* outer)
130 : outer_(outer) {} 133 : outer_(outer) {}
131 134
132 ~TestSchedulerWorkerDelegate() override { 135 ~TestSchedulerWorkerDelegate() override {
133 EXPECT_FALSE(IsCallToDidRunTaskExpected()); 136 EXPECT_FALSE(IsCallToDidRunTaskExpected());
134 } 137 }
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 TaskSchedulerWorkerTest, 351 TaskSchedulerWorkerTest,
349 ::testing::Values(1)); 352 ::testing::Values(1));
350 INSTANTIATE_TEST_CASE_P(TwoTasksPerSequence, 353 INSTANTIATE_TEST_CASE_P(TwoTasksPerSequence,
351 TaskSchedulerWorkerTest, 354 TaskSchedulerWorkerTest,
352 ::testing::Values(2)); 355 ::testing::Values(2));
353 356
354 namespace { 357 namespace {
355 358
356 class ControllableDetachDelegate : public SchedulerWorkerDefaultDelegate { 359 class ControllableDetachDelegate : public SchedulerWorkerDefaultDelegate {
357 public: 360 public:
361 class Controls : public RefCountedThreadSafe<Controls> {
362 public:
363 Controls()
364 : work_running_(WaitableEvent::ResetPolicy::MANUAL,
365 WaitableEvent::InitialState::SIGNALED),
366 work_processed_(WaitableEvent::ResetPolicy::MANUAL,
367 WaitableEvent::InitialState::NOT_SIGNALED),
368 detach_requested_(WaitableEvent::ResetPolicy::MANUAL,
369 WaitableEvent::InitialState::NOT_SIGNALED),
370 detached_(WaitableEvent::ResetPolicy::MANUAL,
371 WaitableEvent::InitialState::NOT_SIGNALED),
372 can_detach_block_(WaitableEvent::ResetPolicy::MANUAL,
373 WaitableEvent::InitialState::SIGNALED),
374 destroyed_(WaitableEvent::ResetPolicy::MANUAL,
375 WaitableEvent::InitialState::NOT_SIGNALED) {}
376
377 void HaveWorkBlock() { work_running_.Reset(); }
378
379 void UnblockWork() { work_running_.Signal(); }
380
381 void MakeCanDetachBlock() { can_detach_block_.Reset(); }
382
383 void UnblockCanDetach() { can_detach_block_.Signal(); }
384
385 void WaitForWorkToRun() { work_processed_.Wait(); }
386
387 void WaitForDetachRequest() { detach_requested_.Wait(); }
388
389 void WaitForDetach() { detached_.Wait(); }
390
391 void WaitForDelegateDestroy() { destroyed_.Wait(); }
392
393 void ResetState() {
394 work_running_.Signal();
395 work_processed_.Reset();
396 detach_requested_.Reset();
397 can_detach_block_.Signal();
398 work_requested_ = false;
399 }
400
401 void set_can_detach(bool can_detach) { can_detach_ = can_detach; }
402
403 private:
404 friend class ControllableDetachDelegate;
405 friend class RefCountedThreadSafe<Controls>;
406 ~Controls() = default;
407
408 WaitableEvent work_running_;
409 WaitableEvent work_processed_;
410 WaitableEvent detach_requested_;
411 WaitableEvent detached_;
412 WaitableEvent can_detach_block_;
413 WaitableEvent destroyed_;
414
415 bool can_detach_ = false;
416 bool work_requested_ = false;
417
418 DISALLOW_COPY_AND_ASSIGN(Controls);
419 };
420
358 ControllableDetachDelegate(TaskTracker* task_tracker) 421 ControllableDetachDelegate(TaskTracker* task_tracker)
359 : task_tracker_(task_tracker), 422 : task_tracker_(task_tracker), controls_(new Controls()) {}
360 work_processed_(WaitableEvent::ResetPolicy::MANUAL,
361 WaitableEvent::InitialState::NOT_SIGNALED),
362 detach_requested_(WaitableEvent::ResetPolicy::MANUAL,
363 WaitableEvent::InitialState::NOT_SIGNALED),
364 detached_(WaitableEvent::ResetPolicy::MANUAL,
365 WaitableEvent::InitialState::NOT_SIGNALED) {
366 EXPECT_TRUE(task_tracker_);
367 }
368 423
369 ~ControllableDetachDelegate() override = default; 424 ~ControllableDetachDelegate() override { controls_->destroyed_.Signal(); }
370
371 // SchedulerWorker::Delegate:
372 MOCK_METHOD1(OnMainEntry, void(SchedulerWorker* worker));
373 425
374 scoped_refptr<Sequence> GetWork(SchedulerWorker* worker) 426 scoped_refptr<Sequence> GetWork(SchedulerWorker* worker)
375 override { 427 override {
376 // Sends one item of work to signal |work_processed_|. On subsequent calls, 428 // Sends one item of work to signal |work_processed_|. On subsequent calls,
377 // sends nullptr to indicate there's no more work to be done. 429 // sends nullptr to indicate there's no more work to be done.
378 if (work_requested_) 430 if (controls_->work_requested_)
379 return nullptr; 431 return nullptr;
380 432
381 work_requested_ = true; 433 controls_->work_requested_ = true;
382 scoped_refptr<Sequence> sequence(new Sequence); 434 scoped_refptr<Sequence> sequence(new Sequence);
383 std::unique_ptr<Task> task(new Task( 435 std::unique_ptr<Task> task(new Task(
384 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&work_processed_)), 436 FROM_HERE,
385 TaskTraits(), TimeDelta())); 437 Bind(
438 [](WaitableEvent* work_processed, WaitableEvent* work_running) {
439 work_processed->Signal();
440 work_running->Wait();
441 },
442 Unretained(&controls_->work_processed_),
443 Unretained(&controls_->work_running_)),
444 TaskTraits().WithBaseSyncPrimitives().WithShutdownBehavior(
445 TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN),
446 TimeDelta()));
386 EXPECT_TRUE(task_tracker_->WillPostTask(task.get())); 447 EXPECT_TRUE(task_tracker_->WillPostTask(task.get()));
387 sequence->PushTask(std::move(task)); 448 sequence->PushTask(std::move(task));
388 return sequence; 449 return sequence;
389 } 450 }
390 451
391 void DidRunTask() override {} 452 void DidRunTask() override {}
392 453
393 bool CanDetach(SchedulerWorker* worker) override { 454 bool CanDetach(SchedulerWorker* worker) override {
394 detach_requested_.Signal(); 455 // Saving |can_detach_| now so that callers waiting on |detach_requested_|
395 return can_detach_; 456 // have the thread go to sleep and then allow detachment.
457 bool can_detach = controls_->can_detach_;
458 controls_->detach_requested_.Signal();
459 controls_->can_detach_block_.Wait();
460 return can_detach;
396 } 461 }
397 462
398 void OnDetach() override { 463 void OnDetach() override {
399 EXPECT_TRUE(can_detach_); 464 EXPECT_TRUE(controls_->can_detach_);
400 EXPECT_TRUE(detach_requested_.IsSignaled()); 465 EXPECT_TRUE(controls_->detach_requested_.IsSignaled());
401 detached_.Signal(); 466 controls_->detached_.Signal();
402 } 467 }
403 468
404 void WaitForWorkToRun() { 469 // ControllableDetachDelegate:
405 work_processed_.Wait(); 470 scoped_refptr<Controls> controls() { return controls_; }
406 }
407
408 void WaitForDetachRequest() {
409 detach_requested_.Wait();
410 }
411
412 void WaitForDetach() { detached_.Wait(); }
413
414 void ResetState() {
415 work_requested_ = false;
416 work_processed_.Reset();
417 detach_requested_.Reset();
418 }
419
420 void set_can_detach(bool can_detach) { can_detach_ = can_detach; }
421 471
422 private: 472 private:
473 scoped_refptr<Sequence> work_sequence_;
423 TaskTracker* const task_tracker_; 474 TaskTracker* const task_tracker_;
424 bool work_requested_ = false; 475 scoped_refptr<Controls> controls_;
425 bool can_detach_ = false;
426 WaitableEvent work_processed_;
427 WaitableEvent detach_requested_;
428 WaitableEvent detached_;
429 476
430 DISALLOW_COPY_AND_ASSIGN(ControllableDetachDelegate); 477 DISALLOW_COPY_AND_ASSIGN(ControllableDetachDelegate);
431 }; 478 };
432 479
480 class MockedControllableDetachDelegate : public ControllableDetachDelegate {
481 public:
482 MockedControllableDetachDelegate(TaskTracker* task_tracker)
483 : ControllableDetachDelegate(task_tracker){};
484 ~MockedControllableDetachDelegate() = default;
485
486 // SchedulerWorker::Delegate:
487 MOCK_METHOD1(OnMainEntry, void(SchedulerWorker* worker));
488
489 private:
490 DISALLOW_COPY_AND_ASSIGN(MockedControllableDetachDelegate);
491 };
492
433 } // namespace 493 } // namespace
434 494
435 TEST(TaskSchedulerWorkerTest, WorkerDetaches) { 495 TEST(TaskSchedulerWorkerTest, WorkerDetaches) {
436 TaskTracker task_tracker; 496 TaskTracker task_tracker;
437 // Will be owned by SchedulerWorker. 497 // Will be owned by SchedulerWorker.
438 ControllableDetachDelegate* delegate = 498 MockedControllableDetachDelegate* delegate =
439 new StrictMock<ControllableDetachDelegate>(&task_tracker); 499 new StrictMock<MockedControllableDetachDelegate>(&task_tracker);
440 delegate->set_can_detach(true); 500 scoped_refptr<ControllableDetachDelegate::Controls> controls =
501 delegate->controls();
502 controls->set_can_detach(true);
441 EXPECT_CALL(*delegate, OnMainEntry(_)); 503 EXPECT_CALL(*delegate, OnMainEntry(_));
442 std::unique_ptr<SchedulerWorker> worker = 504 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
443 SchedulerWorker::Create( 505 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker,
444 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, 506 SchedulerWorker::InitialState::ALIVE);
445 SchedulerWorker::InitialState::ALIVE); 507 worker->WakeUp();
446 worker->WakeUp(); 508 controls->WaitForWorkToRun();
447 delegate->WaitForWorkToRun();
448 Mock::VerifyAndClear(delegate); 509 Mock::VerifyAndClear(delegate);
449 delegate->WaitForDetachRequest(); 510 controls->WaitForDetachRequest();
450 delegate->WaitForDetach(); 511 controls->WaitForDetach();
451 ASSERT_FALSE(worker->ThreadAliveForTesting()); 512 ASSERT_FALSE(worker->ThreadAliveForTesting());
452 } 513 }
453 514
515 TEST(TaskSchedulerWorkerTest, WorkerReleasesBeforeDetach) {
516 TaskTracker task_tracker;
517 // Will be owned by SchedulerWorker.
518 // No mock here as that's reasonably covered by other tests and the delegate
519 // may destroy on a different thread. Mocks aren't designed with that in mind.
520 std::unique_ptr<ControllableDetachDelegate> delegate =
521 MakeUnique<ControllableDetachDelegate>(&task_tracker);
522 scoped_refptr<ControllableDetachDelegate::Controls> controls =
523 delegate->controls();
524
525 controls->set_can_detach(true);
526 controls->MakeCanDetachBlock();
527
528 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
529 ThreadPriority::NORMAL, std::move(delegate), &task_tracker,
530 SchedulerWorker::InitialState::ALIVE);
531 worker->WakeUp();
532
533 controls->WaitForDetachRequest();
534 worker->Cleanup();
535 worker = nullptr;
536 controls->UnblockCanDetach();
537 controls->WaitForDelegateDestroy();
538 }
539
540 TEST(TaskSchedulerWorkerTest, WorkerDetachesAndSelfDestroysAfterDetach) {
541 TaskTracker task_tracker;
542 // Will be owned by SchedulerWorker.
543 // No mock here as that's reasonably covered by other tests and the delegate
544 // may destroy on a different thread. Mocks aren't designed with that in mind.
545 std::unique_ptr<ControllableDetachDelegate> delegate =
546 MakeUnique<ControllableDetachDelegate>(&task_tracker);
547 scoped_refptr<ControllableDetachDelegate::Controls> controls =
548 delegate->controls();
549
550 controls->set_can_detach(true);
551
552 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
553 ThreadPriority::NORMAL, std::move(delegate), &task_tracker,
554 SchedulerWorker::InitialState::ALIVE);
555 worker->WakeUp();
556
557 controls->WaitForDetach();
558 worker->Cleanup();
559 worker = nullptr;
560 controls->WaitForDelegateDestroy();
561 }
562
563 TEST(TaskSchedulerWorkerTest, WorkerDetachesAndSelfDestroysDuringWork) {
564 TaskTracker task_tracker;
565 // Will be owned by SchedulerWorker.
566 // No mock here as that's reasonably covered by other tests and the delegate
567 // may destroy on a different thread. Mocks aren't designed with that in mind.
568 std::unique_ptr<ControllableDetachDelegate> delegate =
569 MakeUnique<ControllableDetachDelegate>(&task_tracker);
570 scoped_refptr<ControllableDetachDelegate::Controls> controls =
571 delegate->controls();
572
573 controls->set_can_detach(true);
574 controls->HaveWorkBlock();
575
576 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
577 ThreadPriority::NORMAL, std::move(delegate), &task_tracker,
578 SchedulerWorker::InitialState::ALIVE);
579 worker->WakeUp();
580
581 controls->WaitForWorkToRun();
582 worker->Cleanup();
583 worker = nullptr;
584 controls->UnblockWork();
585 controls->WaitForDelegateDestroy();
586 }
587
588 TEST(TaskSchedulerWorkerTest, WorkerDetachesAndSelfDestroysDuringWait) {
589 TaskTracker task_tracker;
590 // Will be owned by SchedulerWorker.
591 // No mock here as that's reasonably covered by other tests and the delegate
592 // may destroy on a different thread. Mocks aren't designed with that in mind.
593 std::unique_ptr<ControllableDetachDelegate> delegate =
594 MakeUnique<ControllableDetachDelegate>(&task_tracker);
595 scoped_refptr<ControllableDetachDelegate::Controls> controls =
596 delegate->controls();
597
598 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
599 ThreadPriority::NORMAL, std::move(delegate), &task_tracker,
600 SchedulerWorker::InitialState::ALIVE);
601 worker->WakeUp();
602
603 controls->WaitForDetachRequest();
604 controls->set_can_detach(true);
605 worker->Cleanup();
606 worker = nullptr;
607 controls->WaitForDelegateDestroy();
608 }
609
610 TEST(TaskSchedulerWorkerTest, WorkerDetachesAndSelfDestroysDuringShutdown) {
611 TaskTracker task_tracker;
612 // Will be owned by SchedulerWorker.
613 // No mock here as that's reasonably covered by other tests and the delegate
614 // may destroy on a different thread. Mocks aren't designed with that in mind.
615 std::unique_ptr<ControllableDetachDelegate> delegate =
616 MakeUnique<ControllableDetachDelegate>(&task_tracker);
617 scoped_refptr<ControllableDetachDelegate::Controls> controls =
618 delegate->controls();
619
620 controls->HaveWorkBlock();
621
622 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
623 ThreadPriority::NORMAL, std::move(delegate), &task_tracker,
624 SchedulerWorker::InitialState::ALIVE);
625 worker->WakeUp();
626
627 controls->WaitForWorkToRun();
628 task_tracker.Shutdown();
629 worker->Cleanup();
630 worker = nullptr;
631 controls->UnblockWork();
632 controls->WaitForDelegateDestroy();
633 }
634
635 namespace {
636
637 class CallJoinFromDifferentThread : public SimpleThread {
638 public:
639 CallJoinFromDifferentThread(SchedulerWorker* worker_to_join)
640 : SimpleThread("SchedulerWorkerJoinThread"),
641 worker_to_join_(worker_to_join),
642 run_started_event_(WaitableEvent::ResetPolicy::MANUAL,
643 WaitableEvent::InitialState::NOT_SIGNALED) {}
644
645 ~CallJoinFromDifferentThread() override = default;
646
647 void Run() override {
648 run_started_event_.Signal();
649 worker_to_join_->JoinForTesting();
650 }
651
652 void WaitForRunToStart() { run_started_event_.Wait(); }
653
654 private:
655 SchedulerWorker* const worker_to_join_;
656 WaitableEvent run_started_event_;
657 DISALLOW_COPY_AND_ASSIGN(CallJoinFromDifferentThread);
658 };
659
660 } // namespace
661
662 TEST(TaskSchedulerWorkerTest, WorkerDetachesAndSelfDestroysDuringJoin) {
gab 2017/02/23 21:52:54 As discussed offline, need to tweak test or adjust
robliao 2017/02/23 22:00:03 Nice. This was here since the first revision. Adju
663 TaskTracker task_tracker;
664 // Will be owned by SchedulerWorker.
665 // No mock here as that's reasonably covered by other tests and the
666 // delegate may destroy on a different thread. Mocks aren't designed with that
667 // in mind.
668 std::unique_ptr<ControllableDetachDelegate> delegate =
669 MakeUnique<ControllableDetachDelegate>(&task_tracker);
670 scoped_refptr<ControllableDetachDelegate::Controls> controls =
671 delegate->controls();
672
673 controls->HaveWorkBlock();
674
675 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
676 ThreadPriority::NORMAL, std::move(delegate), &task_tracker,
677 SchedulerWorker::InitialState::ALIVE);
678 worker->WakeUp();
679
680 controls->WaitForWorkToRun();
681 CallJoinFromDifferentThread join_from_different_thread(worker.get());
682 join_from_different_thread.Start();
683 join_from_different_thread.WaitForRunToStart();
684 // Yield here to give the other thread a chance to call JoinForTesting().
685 // Receiving a signal that Run() was called doesn't mean JoinForTesting() was
686 // necessarily called, and we can't signal after JoinForTesting() as
687 // JoinForTesting() blocks until we call UnblockWork().
688 PlatformThread::YieldCurrentThread();
gab 2017/02/23 19:25:24 I'm not convinced yielding is necessary/better. I'
robliao 2017/02/23 21:04:22 Let's go with PlatformThread::Sleep to hammer the
689 worker->Cleanup();
690 worker = nullptr;
691 controls->UnblockWork();
692 controls->WaitForDelegateDestroy();
693 join_from_different_thread.Join();
694 }
695
454 TEST(TaskSchedulerWorkerTest, WorkerDetachesAndWakes) { 696 TEST(TaskSchedulerWorkerTest, WorkerDetachesAndWakes) {
455 TaskTracker task_tracker; 697 TaskTracker task_tracker;
456 // Will be owned by SchedulerWorker. 698 // Will be owned by SchedulerWorker.
457 ControllableDetachDelegate* delegate = 699 MockedControllableDetachDelegate* delegate =
458 new StrictMock<ControllableDetachDelegate>(&task_tracker); 700 new StrictMock<MockedControllableDetachDelegate>(&task_tracker);
459 delegate->set_can_detach(true); 701 scoped_refptr<ControllableDetachDelegate::Controls> controls =
702 delegate->controls();
703
704 controls->set_can_detach(true);
460 EXPECT_CALL(*delegate, OnMainEntry(_)); 705 EXPECT_CALL(*delegate, OnMainEntry(_));
461 std::unique_ptr<SchedulerWorker> worker = 706 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
462 SchedulerWorker::Create( 707 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker,
463 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, 708 SchedulerWorker::InitialState::ALIVE);
464 SchedulerWorker::InitialState::ALIVE); 709 worker->WakeUp();
465 worker->WakeUp(); 710 controls->WaitForWorkToRun();
466 delegate->WaitForWorkToRun();
467 Mock::VerifyAndClear(delegate); 711 Mock::VerifyAndClear(delegate);
468 delegate->WaitForDetachRequest(); 712 controls->WaitForDetachRequest();
469 delegate->WaitForDetach(); 713 controls->WaitForDetach();
470 ASSERT_FALSE(worker->ThreadAliveForTesting()); 714 ASSERT_FALSE(worker->ThreadAliveForTesting());
471 715
472 delegate->ResetState(); 716 controls->ResetState();
473 delegate->set_can_detach(false); 717 controls->set_can_detach(false);
474 // Expect OnMainEntry() to be called when SchedulerWorker recreates its 718 // Expect OnMainEntry() to be called when SchedulerWorker recreates its
475 // thread. 719 // thread.
476 EXPECT_CALL(*delegate, OnMainEntry(worker.get())); 720 EXPECT_CALL(*delegate, OnMainEntry(worker.get()));
477 worker->WakeUp(); 721 worker->WakeUp();
478 delegate->WaitForWorkToRun(); 722 controls->WaitForWorkToRun();
479 Mock::VerifyAndClear(delegate); 723 Mock::VerifyAndClear(delegate);
480 delegate->WaitForDetachRequest(); 724 controls->WaitForDetachRequest();
481 delegate->WaitForDetach(); 725 controls->WaitForDetach();
482 ASSERT_TRUE(worker->ThreadAliveForTesting()); 726 ASSERT_TRUE(worker->ThreadAliveForTesting());
483 worker->JoinForTesting(); 727 worker->JoinForTesting();
484 } 728 }
485 729
486 TEST(TaskSchedulerWorkerTest, CreateDetached) { 730 TEST(TaskSchedulerWorkerTest, CreateDetached) {
487 TaskTracker task_tracker; 731 TaskTracker task_tracker;
488 // Will be owned by SchedulerWorker. 732 // Will be owned by SchedulerWorker.
489 ControllableDetachDelegate* delegate = 733 MockedControllableDetachDelegate* delegate =
490 new StrictMock<ControllableDetachDelegate>(&task_tracker); 734 new StrictMock<MockedControllableDetachDelegate>(&task_tracker);
491 std::unique_ptr<SchedulerWorker> worker = 735 scoped_refptr<ControllableDetachDelegate::Controls> controls =
492 SchedulerWorker::Create( 736 delegate->controls();
493 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, 737 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
494 SchedulerWorker::InitialState::DETACHED); 738 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker,
739 SchedulerWorker::InitialState::DETACHED);
495 ASSERT_FALSE(worker->ThreadAliveForTesting()); 740 ASSERT_FALSE(worker->ThreadAliveForTesting());
496 EXPECT_CALL(*delegate, OnMainEntry(worker.get())); 741 EXPECT_CALL(*delegate, OnMainEntry(worker.get()));
497 worker->WakeUp(); 742 worker->WakeUp();
498 delegate->WaitForWorkToRun(); 743 controls->WaitForWorkToRun();
499 Mock::VerifyAndClear(delegate); 744 Mock::VerifyAndClear(delegate);
500 delegate->WaitForDetachRequest(); 745 controls->WaitForDetachRequest();
501 ASSERT_TRUE(worker->ThreadAliveForTesting()); 746 ASSERT_TRUE(worker->ThreadAliveForTesting());
502 worker->JoinForTesting(); 747 worker->JoinForTesting();
503 } 748 }
504 749
505 namespace { 750 namespace {
506 751
507 class ExpectThreadPriorityDelegate : public SchedulerWorkerDefaultDelegate { 752 class ExpectThreadPriorityDelegate : public SchedulerWorkerDefaultDelegate {
508 public: 753 public:
509 ExpectThreadPriorityDelegate() 754 ExpectThreadPriorityDelegate()
510 : priority_verified_in_get_work_event_( 755 : priority_verified_in_get_work_event_(
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 TaskTracker task_tracker; 798 TaskTracker task_tracker;
554 799
555 std::unique_ptr<ExpectThreadPriorityDelegate> delegate( 800 std::unique_ptr<ExpectThreadPriorityDelegate> delegate(
556 new ExpectThreadPriorityDelegate); 801 new ExpectThreadPriorityDelegate);
557 ExpectThreadPriorityDelegate* delegate_raw = delegate.get(); 802 ExpectThreadPriorityDelegate* delegate_raw = delegate.get();
558 delegate_raw->SetExpectedThreadPriority( 803 delegate_raw->SetExpectedThreadPriority(
559 PlatformThread::CanIncreaseCurrentThreadPriority() 804 PlatformThread::CanIncreaseCurrentThreadPriority()
560 ? ThreadPriority::BACKGROUND 805 ? ThreadPriority::BACKGROUND
561 : ThreadPriority::NORMAL); 806 : ThreadPriority::NORMAL);
562 807
563 std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( 808 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
564 ThreadPriority::BACKGROUND, std::move(delegate), &task_tracker, 809 ThreadPriority::BACKGROUND, std::move(delegate), &task_tracker,
565 SchedulerWorker::InitialState::ALIVE); 810 SchedulerWorker::InitialState::ALIVE);
566 811
567 // Verify that the initial thread priority is BACKGROUND (or NORMAL if thread 812 // Verify that the initial thread priority is BACKGROUND (or NORMAL if thread
568 // priority can't be increased). 813 // priority can't be increased).
569 worker->WakeUp(); 814 worker->WakeUp();
570 delegate_raw->WaitForPriorityVerifiedInGetWork(); 815 delegate_raw->WaitForPriorityVerifiedInGetWork();
571 816
572 // Verify that the thread priority is bumped to NORMAL during shutdown. 817 // Verify that the thread priority is bumped to NORMAL during shutdown.
573 delegate_raw->SetExpectedThreadPriority(ThreadPriority::NORMAL); 818 delegate_raw->SetExpectedThreadPriority(ThreadPriority::NORMAL);
574 task_tracker.SetHasShutdownStartedForTesting(); 819 task_tracker.SetHasShutdownStartedForTesting();
575 worker->WakeUp(); 820 worker->WakeUp();
576 delegate_raw->WaitForPriorityVerifiedInGetWork(); 821 delegate_raw->WaitForPriorityVerifiedInGetWork();
577 822
578 worker->JoinForTesting(); 823 worker->JoinForTesting();
579 } 824 }
580 825
581 TEST(TaskSchedulerWorkerTest, BumpPriorityOfDetachedThreadDuringShutdown) { 826 TEST(TaskSchedulerWorkerTest, BumpPriorityOfDetachedThreadDuringShutdown) {
582 TaskTracker task_tracker; 827 TaskTracker task_tracker;
583 828
584 std::unique_ptr<ExpectThreadPriorityDelegate> delegate( 829 std::unique_ptr<ExpectThreadPriorityDelegate> delegate(
585 new ExpectThreadPriorityDelegate); 830 new ExpectThreadPriorityDelegate);
586 ExpectThreadPriorityDelegate* delegate_raw = delegate.get(); 831 ExpectThreadPriorityDelegate* delegate_raw = delegate.get();
587 delegate_raw->SetExpectedThreadPriority(ThreadPriority::NORMAL); 832 delegate_raw->SetExpectedThreadPriority(ThreadPriority::NORMAL);
588 833
589 // Create a DETACHED thread. 834 // Create a DETACHED thread.
590 std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( 835 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
591 ThreadPriority::BACKGROUND, std::move(delegate), &task_tracker, 836 ThreadPriority::BACKGROUND, std::move(delegate), &task_tracker,
592 SchedulerWorker::InitialState::DETACHED); 837 SchedulerWorker::InitialState::DETACHED);
593 838
594 // Pretend that shutdown has started. 839 // Pretend that shutdown has started.
595 task_tracker.SetHasShutdownStartedForTesting(); 840 task_tracker.SetHasShutdownStartedForTesting();
596 841
597 // Wake up the thread and verify that its priority is NORMAL when 842 // Wake up the thread and verify that its priority is NORMAL when
598 // OnMainEntry() and GetWork() are called. 843 // OnMainEntry() and GetWork() are called.
599 worker->WakeUp(); 844 worker->WakeUp();
600 delegate_raw->WaitForPriorityVerifiedInGetWork(); 845 delegate_raw->WaitForPriorityVerifiedInGetWork();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 // COM library wasn't already initialized on the thread. 921 // COM library wasn't already initialized on the thread.
677 EXPECT_EQ(S_OK, delegate_raw->coinitialize_hresult()); 922 EXPECT_EQ(S_OK, delegate_raw->coinitialize_hresult());
678 923
679 worker->JoinForTesting(); 924 worker->JoinForTesting();
680 } 925 }
681 926
682 #endif // defined(OS_WIN) 927 #endif // defined(OS_WIN)
683 928
684 } // namespace internal 929 } // namespace internal
685 } // namespace base 930 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698