Chromium Code Reviews| Index: base/task_scheduler/scheduler_worker_unittest.cc |
| diff --git a/base/task_scheduler/scheduler_worker_unittest.cc b/base/task_scheduler/scheduler_worker_unittest.cc |
| index 437bbedfdb5472dd74a6e45def138c4667dee6b9..b2228ded1052f0547b3b3d241bb2a30349ec3293 100644 |
| --- a/base/task_scheduler/scheduler_worker_unittest.cc |
| +++ b/base/task_scheduler/scheduler_worker_unittest.cc |
| @@ -14,10 +14,12 @@ |
| #include "base/macros.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/synchronization/condition_variable.h" |
| +#include "base/synchronization/waitable_event.h" |
| #include "base/task_scheduler/scheduler_lock.h" |
| #include "base/task_scheduler/sequence.h" |
| #include "base/task_scheduler/task.h" |
| #include "base/task_scheduler/task_tracker.h" |
| +#include "base/threading/platform_thread.h" |
| #include "base/time/time.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| @@ -421,6 +423,106 @@ TEST(TaskSchedulerWorkerTest, CreateDetached) { |
| worker->JoinForTesting(); |
| } |
| +namespace { |
| + |
| +class ExpectThreadPriorityDelegate : public SchedulerWorker::Delegate { |
| + public: |
| + ExpectThreadPriorityDelegate() |
| + : priority_verified_in_get_work_event_( |
| + WaitableEvent::ResetPolicy::AUTOMATIC, |
| + WaitableEvent::InitialState::NOT_SIGNALED), |
| + expected_thread_priority_(ThreadPriority::BACKGROUND) {} |
| + |
| + void SetExpectedThreadPriority(ThreadPriority expected_thread_priority) { |
| + expected_thread_priority_ = expected_thread_priority; |
| + } |
| + |
| + void WaitForPriorityVerifiedInGetWork() { |
| + priority_verified_in_get_work_event_.Wait(); |
| + } |
| + |
| + // SchedulerWorker::Delegate: |
| + void OnMainEntry(SchedulerWorker* worker) override { VerifyThreadPriority(); } |
| + scoped_refptr<Sequence> GetWork(SchedulerWorker* worker) override { |
| + VerifyThreadPriority(); |
| + priority_verified_in_get_work_event_.Signal(); |
| + return nullptr; |
| + } |
| + void ReEnqueueSequence(scoped_refptr<Sequence> sequence) override {} |
| + TimeDelta GetSleepTimeout() override { return TimeDelta::Max(); } |
| + bool CanDetach(SchedulerWorker* worker) override { return false; } |
| + |
| + private: |
| + void VerifyThreadPriority() { |
| + AutoSchedulerLock auto_lock(expected_thread_priority_lock_); |
| + EXPECT_EQ(expected_thread_priority_, |
| + PlatformThread::GetCurrentThreadPriority()); |
| + } |
| + |
| + // Signaled after GetWork() has verified the priority of the worker thread. |
| + WaitableEvent priority_verified_in_get_work_event_; |
| + |
| + // Synchronizes access to |expected_thread_priority_|. |
| + SchedulerLock expected_thread_priority_lock_; |
| + |
| + // Expected thread priority for the next call to OnMainEntry() or GetWork(). |
| + ThreadPriority expected_thread_priority_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ExpectThreadPriorityDelegate); |
| +}; |
| + |
| +} // namespace |
| + |
| +TEST(TaskSchedulerWorkerTest, BumpPriorityOfAliveThreadDuringShutdown) { |
| + TaskTracker task_tracker; |
| + |
| + std::unique_ptr<ExpectThreadPriorityDelegate> delegate( |
| + new ExpectThreadPriorityDelegate); |
| + ExpectThreadPriorityDelegate* delegate_raw = delegate.get(); |
| + delegate_raw->SetExpectedThreadPriority(ThreadPriority::BACKGROUND); |
| + |
| + // Create an ALIVE thread. |
|
robliao
2016/07/20 22:31:48
Nit: Remove this comment.
fdoray
2016/07/21 13:21:56
Done.
|
| + std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( |
| + ThreadPriority::BACKGROUND, std::move(delegate), &task_tracker, |
| + SchedulerWorker::InitialState::ALIVE); |
| + |
| + // Verify that the initial thread priority is BACKGROUND. |
| + worker->WakeUp(); |
| + delegate_raw->WaitForPriorityVerifiedInGetWork(); |
| + |
| + // Verify that the thread priority is bumped to NORMAL during shutdown. |
| + delegate_raw->SetExpectedThreadPriority(ThreadPriority::NORMAL); |
| + task_tracker.SetHasShutdownStartedForTesting(); |
| + worker->WakeUp(); |
| + delegate_raw->WaitForPriorityVerifiedInGetWork(); |
| + |
| + worker->JoinForTesting(); |
| +} |
| + |
| +TEST(TaskSchedulerWorkerTest, BumpPriorityOfDetachedThreadDuringShutdown) { |
| + TaskTracker task_tracker; |
| + |
| + std::unique_ptr<ExpectThreadPriorityDelegate> delegate( |
| + new ExpectThreadPriorityDelegate); |
| + ExpectThreadPriorityDelegate* delegate_raw = delegate.get(); |
| + delegate_raw->SetExpectedThreadPriority(ThreadPriority::NORMAL); |
| + |
| + // Create a DETACHED thread. |
| + std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( |
| + ThreadPriority::BACKGROUND, std::move(delegate), &task_tracker, |
| + SchedulerWorker::InitialState::DETACHED); |
| + |
| + // Pretend that shutdown has started. |
| + task_tracker.SetHasShutdownStartedForTesting(); |
| + |
| + // Wake up the thread and verify that its priority is NORMAL when |
| + // OnMainEntry() and GetWork() are called. |
| + worker->WakeUp(); |
| + delegate_raw->WaitForPriorityVerifiedInGetWork(); |
| + |
| + worker->JoinForTesting(); |
| +} |
| + |
| } // namespace |
| } // namespace internal |
| } // namespace base |