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

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

Issue 2692863012: SchedulerWorker Refcounting for Destruction in Production (Closed)
Patch Set: Remove Last Vestiges of std::unique_ptr SchedulerWorker 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
« no previous file with comments | « base/task_scheduler/scheduler_worker_stack_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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, WorkerCleanupBeforeDetach) {
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, WorkerCleanupAfterDetach) {
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, WorkerCleanupDuringWork) {
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->HaveWorkBlock();
574
575 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
576 ThreadPriority::NORMAL, std::move(delegate), &task_tracker,
577 SchedulerWorker::InitialState::ALIVE);
578 worker->WakeUp();
579
580 controls->WaitForWorkToRun();
581 worker->Cleanup();
582 worker = nullptr;
583 controls->UnblockWork();
584 controls->WaitForDelegateDestroy();
585 }
586
587 TEST(TaskSchedulerWorkerTest, WorkerCleanupDuringWait) {
588 TaskTracker task_tracker;
589 // Will be owned by SchedulerWorker.
590 // No mock here as that's reasonably covered by other tests and the delegate
591 // may destroy on a different thread. Mocks aren't designed with that in mind.
592 std::unique_ptr<ControllableDetachDelegate> delegate =
593 MakeUnique<ControllableDetachDelegate>(&task_tracker);
594 scoped_refptr<ControllableDetachDelegate::Controls> controls =
595 delegate->controls();
596
597 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
598 ThreadPriority::NORMAL, std::move(delegate), &task_tracker,
599 SchedulerWorker::InitialState::ALIVE);
600 worker->WakeUp();
601
602 controls->WaitForDetachRequest();
603 worker->Cleanup();
604 worker = nullptr;
605 controls->WaitForDelegateDestroy();
606 }
607
608 TEST(TaskSchedulerWorkerTest, WorkerCleanupDuringShutdown) {
609 TaskTracker task_tracker;
610 // Will be owned by SchedulerWorker.
611 // No mock here as that's reasonably covered by other tests and the delegate
612 // may destroy on a different thread. Mocks aren't designed with that in mind.
613 std::unique_ptr<ControllableDetachDelegate> delegate =
614 MakeUnique<ControllableDetachDelegate>(&task_tracker);
615 scoped_refptr<ControllableDetachDelegate::Controls> controls =
616 delegate->controls();
617
618 controls->HaveWorkBlock();
619
620 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
621 ThreadPriority::NORMAL, std::move(delegate), &task_tracker,
622 SchedulerWorker::InitialState::ALIVE);
623 worker->WakeUp();
624
625 controls->WaitForWorkToRun();
626 task_tracker.Shutdown();
627 worker->Cleanup();
628 worker = nullptr;
629 controls->UnblockWork();
630 controls->WaitForDelegateDestroy();
631 }
632
633 namespace {
634
635 class CallJoinFromDifferentThread : public SimpleThread {
636 public:
637 CallJoinFromDifferentThread(SchedulerWorker* worker_to_join)
638 : SimpleThread("SchedulerWorkerJoinThread"),
639 worker_to_join_(worker_to_join),
640 run_started_event_(WaitableEvent::ResetPolicy::MANUAL,
641 WaitableEvent::InitialState::NOT_SIGNALED) {}
642
643 ~CallJoinFromDifferentThread() override = default;
644
645 void Run() override {
646 run_started_event_.Signal();
647 worker_to_join_->JoinForTesting();
648 }
649
650 void WaitForRunToStart() { run_started_event_.Wait(); }
651
652 private:
653 SchedulerWorker* const worker_to_join_;
654 WaitableEvent run_started_event_;
655 DISALLOW_COPY_AND_ASSIGN(CallJoinFromDifferentThread);
656 };
657
658 } // namespace
659
660 TEST(TaskSchedulerWorkerTest, WorkerCleanupDuringJoin) {
661 TaskTracker task_tracker;
662 // Will be owned by SchedulerWorker.
663 // No mock here as that's reasonably covered by other tests and the
664 // delegate may destroy on a different thread. Mocks aren't designed with that
665 // in mind.
666 std::unique_ptr<ControllableDetachDelegate> delegate =
667 MakeUnique<ControllableDetachDelegate>(&task_tracker);
668 scoped_refptr<ControllableDetachDelegate::Controls> controls =
669 delegate->controls();
670
671 controls->HaveWorkBlock();
672
673 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
674 ThreadPriority::NORMAL, std::move(delegate), &task_tracker,
675 SchedulerWorker::InitialState::ALIVE);
676 worker->WakeUp();
677
678 controls->WaitForWorkToRun();
679 CallJoinFromDifferentThread join_from_different_thread(worker.get());
680 join_from_different_thread.Start();
681 join_from_different_thread.WaitForRunToStart();
682 // Sleep here to give the other thread a chance to call JoinForTesting().
683 // Receiving a signal that Run() was called doesn't mean JoinForTesting() was
684 // necessarily called, and we can't signal after JoinForTesting() as
685 // JoinForTesting() blocks until we call UnblockWork().
686 PlatformThread::Sleep(TestTimeouts::tiny_timeout());
687 worker->Cleanup();
688 worker = nullptr;
689 controls->UnblockWork();
690 controls->WaitForDelegateDestroy();
691 join_from_different_thread.Join();
692 }
693
454 TEST(TaskSchedulerWorkerTest, WorkerDetachesAndWakes) { 694 TEST(TaskSchedulerWorkerTest, WorkerDetachesAndWakes) {
455 TaskTracker task_tracker; 695 TaskTracker task_tracker;
456 // Will be owned by SchedulerWorker. 696 // Will be owned by SchedulerWorker.
457 ControllableDetachDelegate* delegate = 697 MockedControllableDetachDelegate* delegate =
458 new StrictMock<ControllableDetachDelegate>(&task_tracker); 698 new StrictMock<MockedControllableDetachDelegate>(&task_tracker);
459 delegate->set_can_detach(true); 699 scoped_refptr<ControllableDetachDelegate::Controls> controls =
700 delegate->controls();
701
702 controls->set_can_detach(true);
460 EXPECT_CALL(*delegate, OnMainEntry(_)); 703 EXPECT_CALL(*delegate, OnMainEntry(_));
461 std::unique_ptr<SchedulerWorker> worker = 704 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
462 SchedulerWorker::Create( 705 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker,
463 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, 706 SchedulerWorker::InitialState::ALIVE);
464 SchedulerWorker::InitialState::ALIVE); 707 worker->WakeUp();
465 worker->WakeUp(); 708 controls->WaitForWorkToRun();
466 delegate->WaitForWorkToRun();
467 Mock::VerifyAndClear(delegate); 709 Mock::VerifyAndClear(delegate);
468 delegate->WaitForDetachRequest(); 710 controls->WaitForDetachRequest();
469 delegate->WaitForDetach(); 711 controls->WaitForDetach();
470 ASSERT_FALSE(worker->ThreadAliveForTesting()); 712 ASSERT_FALSE(worker->ThreadAliveForTesting());
471 713
472 delegate->ResetState(); 714 controls->ResetState();
473 delegate->set_can_detach(false); 715 controls->set_can_detach(false);
474 // Expect OnMainEntry() to be called when SchedulerWorker recreates its 716 // Expect OnMainEntry() to be called when SchedulerWorker recreates its
475 // thread. 717 // thread.
476 EXPECT_CALL(*delegate, OnMainEntry(worker.get())); 718 EXPECT_CALL(*delegate, OnMainEntry(worker.get()));
477 worker->WakeUp(); 719 worker->WakeUp();
478 delegate->WaitForWorkToRun(); 720 controls->WaitForWorkToRun();
479 Mock::VerifyAndClear(delegate); 721 Mock::VerifyAndClear(delegate);
480 delegate->WaitForDetachRequest(); 722 controls->WaitForDetachRequest();
481 delegate->WaitForDetach(); 723 controls->WaitForDetach();
482 ASSERT_TRUE(worker->ThreadAliveForTesting()); 724 ASSERT_TRUE(worker->ThreadAliveForTesting());
483 worker->JoinForTesting(); 725 worker->JoinForTesting();
484 } 726 }
485 727
486 TEST(TaskSchedulerWorkerTest, CreateDetached) { 728 TEST(TaskSchedulerWorkerTest, CreateDetached) {
487 TaskTracker task_tracker; 729 TaskTracker task_tracker;
488 // Will be owned by SchedulerWorker. 730 // Will be owned by SchedulerWorker.
489 ControllableDetachDelegate* delegate = 731 MockedControllableDetachDelegate* delegate =
490 new StrictMock<ControllableDetachDelegate>(&task_tracker); 732 new StrictMock<MockedControllableDetachDelegate>(&task_tracker);
491 std::unique_ptr<SchedulerWorker> worker = 733 scoped_refptr<ControllableDetachDelegate::Controls> controls =
492 SchedulerWorker::Create( 734 delegate->controls();
493 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, 735 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
494 SchedulerWorker::InitialState::DETACHED); 736 ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker,
737 SchedulerWorker::InitialState::DETACHED);
495 ASSERT_FALSE(worker->ThreadAliveForTesting()); 738 ASSERT_FALSE(worker->ThreadAliveForTesting());
496 EXPECT_CALL(*delegate, OnMainEntry(worker.get())); 739 EXPECT_CALL(*delegate, OnMainEntry(worker.get()));
497 worker->WakeUp(); 740 worker->WakeUp();
498 delegate->WaitForWorkToRun(); 741 controls->WaitForWorkToRun();
499 Mock::VerifyAndClear(delegate); 742 Mock::VerifyAndClear(delegate);
500 delegate->WaitForDetachRequest(); 743 controls->WaitForDetachRequest();
501 ASSERT_TRUE(worker->ThreadAliveForTesting()); 744 ASSERT_TRUE(worker->ThreadAliveForTesting());
502 worker->JoinForTesting(); 745 worker->JoinForTesting();
503 } 746 }
504 747
505 namespace { 748 namespace {
506 749
507 class ExpectThreadPriorityDelegate : public SchedulerWorkerDefaultDelegate { 750 class ExpectThreadPriorityDelegate : public SchedulerWorkerDefaultDelegate {
508 public: 751 public:
509 ExpectThreadPriorityDelegate() 752 ExpectThreadPriorityDelegate()
510 : priority_verified_in_get_work_event_( 753 : priority_verified_in_get_work_event_(
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 TaskTracker task_tracker; 796 TaskTracker task_tracker;
554 797
555 std::unique_ptr<ExpectThreadPriorityDelegate> delegate( 798 std::unique_ptr<ExpectThreadPriorityDelegate> delegate(
556 new ExpectThreadPriorityDelegate); 799 new ExpectThreadPriorityDelegate);
557 ExpectThreadPriorityDelegate* delegate_raw = delegate.get(); 800 ExpectThreadPriorityDelegate* delegate_raw = delegate.get();
558 delegate_raw->SetExpectedThreadPriority( 801 delegate_raw->SetExpectedThreadPriority(
559 PlatformThread::CanIncreaseCurrentThreadPriority() 802 PlatformThread::CanIncreaseCurrentThreadPriority()
560 ? ThreadPriority::BACKGROUND 803 ? ThreadPriority::BACKGROUND
561 : ThreadPriority::NORMAL); 804 : ThreadPriority::NORMAL);
562 805
563 std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( 806 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
564 ThreadPriority::BACKGROUND, std::move(delegate), &task_tracker, 807 ThreadPriority::BACKGROUND, std::move(delegate), &task_tracker,
565 SchedulerWorker::InitialState::ALIVE); 808 SchedulerWorker::InitialState::ALIVE);
566 809
567 // Verify that the initial thread priority is BACKGROUND (or NORMAL if thread 810 // Verify that the initial thread priority is BACKGROUND (or NORMAL if thread
568 // priority can't be increased). 811 // priority can't be increased).
569 worker->WakeUp(); 812 worker->WakeUp();
570 delegate_raw->WaitForPriorityVerifiedInGetWork(); 813 delegate_raw->WaitForPriorityVerifiedInGetWork();
571 814
572 // Verify that the thread priority is bumped to NORMAL during shutdown. 815 // Verify that the thread priority is bumped to NORMAL during shutdown.
573 delegate_raw->SetExpectedThreadPriority(ThreadPriority::NORMAL); 816 delegate_raw->SetExpectedThreadPriority(ThreadPriority::NORMAL);
574 task_tracker.SetHasShutdownStartedForTesting(); 817 task_tracker.SetHasShutdownStartedForTesting();
575 worker->WakeUp(); 818 worker->WakeUp();
576 delegate_raw->WaitForPriorityVerifiedInGetWork(); 819 delegate_raw->WaitForPriorityVerifiedInGetWork();
577 820
578 worker->JoinForTesting(); 821 worker->JoinForTesting();
579 } 822 }
580 823
581 TEST(TaskSchedulerWorkerTest, BumpPriorityOfDetachedThreadDuringShutdown) { 824 TEST(TaskSchedulerWorkerTest, BumpPriorityOfDetachedThreadDuringShutdown) {
582 TaskTracker task_tracker; 825 TaskTracker task_tracker;
583 826
584 std::unique_ptr<ExpectThreadPriorityDelegate> delegate( 827 std::unique_ptr<ExpectThreadPriorityDelegate> delegate(
585 new ExpectThreadPriorityDelegate); 828 new ExpectThreadPriorityDelegate);
586 ExpectThreadPriorityDelegate* delegate_raw = delegate.get(); 829 ExpectThreadPriorityDelegate* delegate_raw = delegate.get();
587 delegate_raw->SetExpectedThreadPriority(ThreadPriority::NORMAL); 830 delegate_raw->SetExpectedThreadPriority(ThreadPriority::NORMAL);
588 831
589 // Create a DETACHED thread. 832 // Create a DETACHED thread.
590 std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( 833 scoped_refptr<SchedulerWorker> worker = SchedulerWorker::Create(
591 ThreadPriority::BACKGROUND, std::move(delegate), &task_tracker, 834 ThreadPriority::BACKGROUND, std::move(delegate), &task_tracker,
592 SchedulerWorker::InitialState::DETACHED); 835 SchedulerWorker::InitialState::DETACHED);
593 836
594 // Pretend that shutdown has started. 837 // Pretend that shutdown has started.
595 task_tracker.SetHasShutdownStartedForTesting(); 838 task_tracker.SetHasShutdownStartedForTesting();
596 839
597 // Wake up the thread and verify that its priority is NORMAL when 840 // Wake up the thread and verify that its priority is NORMAL when
598 // OnMainEntry() and GetWork() are called. 841 // OnMainEntry() and GetWork() are called.
599 worker->WakeUp(); 842 worker->WakeUp();
600 delegate_raw->WaitForPriorityVerifiedInGetWork(); 843 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. 919 // COM library wasn't already initialized on the thread.
677 EXPECT_EQ(S_OK, delegate_raw->coinitialize_hresult()); 920 EXPECT_EQ(S_OK, delegate_raw->coinitialize_hresult());
678 921
679 worker->JoinForTesting(); 922 worker->JoinForTesting();
680 } 923 }
681 924
682 #endif // defined(OS_WIN) 925 #endif // defined(OS_WIN)
683 926
684 } // namespace internal 927 } // namespace internal
685 } // namespace base 928 } // namespace base
OLDNEW
« no previous file with comments | « base/task_scheduler/scheduler_worker_stack_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698