Chromium Code Reviews| Index: base/task_scheduler/scheduler_worker_thread_unittest.cc |
| diff --git a/base/task_scheduler/scheduler_worker_thread_unittest.cc b/base/task_scheduler/scheduler_worker_thread_unittest.cc |
| index 88d9b23c8f2a5199d45245cd67a10df4752a12e5..18710b7f322c6d699131054e07784bf0a1fd50a7 100644 |
| --- a/base/task_scheduler/scheduler_worker_thread_unittest.cc |
| +++ b/base/task_scheduler/scheduler_worker_thread_unittest.cc |
| @@ -41,7 +41,8 @@ class TaskSchedulerWorkerThreadTest : public testing::TestWithParam<size_t> { |
| worker_thread_ = SchedulerWorkerThread::Create( |
| ThreadPriority::NORMAL, |
| WrapUnique(new TestSchedulerWorkerThreadDelegate(this)), |
| - &task_tracker_); |
| + &task_tracker_, |
| + SchedulerWorkerThread::InitialWorkerState::ALIVE); |
| ASSERT_TRUE(worker_thread_); |
| worker_thread_set_.Signal(); |
| main_entry_called_.Wait(); |
| @@ -172,6 +173,10 @@ class TaskSchedulerWorkerThreadTest : public testing::TestWithParam<size_t> { |
| return TimeDelta::Max(); |
| } |
| + bool CanDetach(SchedulerWorkerThread* worker_thread) override { |
| + return false; |
| + } |
| + |
| private: |
| TaskSchedulerWorkerThreadTest* outer_; |
| }; |
| @@ -286,6 +291,137 @@ INSTANTIATE_TEST_CASE_P(TwoTasksPerSequence, |
| TaskSchedulerWorkerThreadTest, |
| ::testing::Values(2)); |
| +namespace { |
| + |
| +class ControllableDetachDelegate : public SchedulerWorkerThread::Delegate { |
| + public: |
| + ControllableDetachDelegate() |
| + : work_requested_(false), |
| + can_detach_(false), |
| + work_processed_(WaitableEvent::ResetPolicy::MANUAL, |
| + WaitableEvent::InitialState::NOT_SIGNALED), |
| + detach_requested_(WaitableEvent::ResetPolicy::MANUAL, |
| + WaitableEvent::InitialState::NOT_SIGNALED) {} |
| + |
| + ~ControllableDetachDelegate() override = default; |
| + |
| + // SchedulerWorkerThread::Delegate: |
| + void OnMainEntry(SchedulerWorkerThread* worker_thread) override {} |
| + |
| + scoped_refptr<Sequence> GetWork(SchedulerWorkerThread* worker_thread) |
|
gab
2016/06/10 16:15:21
Document what this does.
robliao
2016/06/10 18:03:42
Done.
|
| + override { |
| + if (work_requested_) |
| + return nullptr; |
| + |
| + work_requested_ = true; |
| + scoped_refptr<Sequence> sequence(new Sequence); |
| + std::unique_ptr<Task> task(new Task( |
| + FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&work_processed_)), |
| + TaskTraits(), TimeDelta())); |
| + sequence->PushTask(std::move(task)); |
| + return sequence; |
| + } |
| + |
| + void ReEnqueueSequence(scoped_refptr<Sequence> sequence) override { |
| + NOTREACHED() << |
| + "GetWork() never returns a sequence so there's nothing to reenqueue."; |
|
gab
2016/06/10 16:15:21
That's not true : it does return a sequence but it
robliao
2016/06/10 18:03:42
Indeed! Updated this copy+paste line.
|
| + } |
| + |
| + TimeDelta GetSleepTimeout() override { |
| + return TimeDelta::Max(); |
| + } |
| + |
| + bool CanDetach(SchedulerWorkerThread* worker_thread) override { |
| + detach_requested_.Signal(); |
| + return can_detach_; |
| + } |
| + |
| + void WaitForWorkToRun() { |
| + work_processed_.Wait(); |
| + } |
| + |
| + void WaitForDetachRequest() { |
| + detach_requested_.Wait(); |
| + } |
| + |
| + void ResetAll() { |
| + work_requested_ = false; |
| + work_processed_.Reset(); |
| + detach_requested_.Reset(); |
| + } |
| + |
| + void set_can_detach(bool can_detach) { can_detach_ = can_detach; } |
| + |
| + private: |
| + bool work_requested_; |
| + bool can_detach_; |
|
gab
2016/06/10 16:15:21
= false; for 2 lines above instead of in construct
robliao
2016/06/10 18:03:42
Done. It's too bad we can't do the same for non-PO
|
| + WaitableEvent work_processed_; |
| + WaitableEvent detach_requested_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ControllableDetachDelegate); |
| +}; |
| + |
| +} // namespace |
| + |
| +TEST(TaskSchedulerWorkerThreadTest, WorkerDetaches) { |
| + TaskTracker task_tracker; |
| + // Will be owned by SchedulerWorkerThread. |
| + ControllableDetachDelegate* delegate = new ControllableDetachDelegate; |
| + delegate->set_can_detach(true); |
| + std::unique_ptr<SchedulerWorkerThread> worker_thread = |
| + SchedulerWorkerThread::Create( |
| + ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, |
| + SchedulerWorkerThread::InitialWorkerState::ALIVE); |
| + worker_thread->WakeUp(); |
| + delegate->WaitForWorkToRun(); |
| + delegate->WaitForDetachRequest(); |
| + // Sleep to give a chance for the detach to happen. A yield is too short. |
| + PlatformThread::Sleep(TimeDelta::FromMilliseconds(50)); |
| + ASSERT_FALSE(worker_thread->WorkerAliveForTesting()); |
| +} |
| + |
| +TEST(TaskSchedulerWorkerThreadTest, WorkerDetachesAndWakes) { |
| + TaskTracker task_tracker; |
| + // Will be owned by SchedulerWorkerThread. |
| + ControllableDetachDelegate* delegate = new ControllableDetachDelegate; |
| + delegate->set_can_detach(true); |
| + std::unique_ptr<SchedulerWorkerThread> worker_thread = |
| + SchedulerWorkerThread::Create( |
| + ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, |
| + SchedulerWorkerThread::InitialWorkerState::ALIVE); |
| + worker_thread->WakeUp(); |
| + delegate->WaitForWorkToRun(); |
| + delegate->WaitForDetachRequest(); |
| + // Sleep to give a chance for the detach to happen. A yield is too short. |
| + PlatformThread::Sleep(TimeDelta::FromMilliseconds(50)); |
| + ASSERT_FALSE(worker_thread->WorkerAliveForTesting()); |
| + |
| + delegate->ResetAll(); |
| + delegate->set_can_detach(false); |
|
gab
2016/06/10 16:15:21
I'd expected ResetAll() to also reset "detach" to
robliao
2016/06/10 18:03:42
This used to be ResetAllAndDisallowDetach, but tha
|
| + worker_thread->WakeUp(); |
| + delegate->WaitForWorkToRun(); |
| + delegate->WaitForDetachRequest(); |
| + PlatformThread::Sleep(TimeDelta::FromMilliseconds(50)); |
| + ASSERT_TRUE(worker_thread->WorkerAliveForTesting()); |
| + worker_thread->JoinForTesting(); |
| +} |
| + |
| +TEST(TaskSchedulerWorkerThreadTest, CreateDetached) { |
| + TaskTracker task_tracker; |
| + // Will be owned by SchedulerWorkerThread. |
| + ControllableDetachDelegate* delegate = new ControllableDetachDelegate; |
| + std::unique_ptr<SchedulerWorkerThread> worker_thread = |
| + SchedulerWorkerThread::Create( |
| + ThreadPriority::NORMAL, WrapUnique(delegate), &task_tracker, |
| + SchedulerWorkerThread::InitialWorkerState::DETACHED); |
| + ASSERT_FALSE(worker_thread->WorkerAliveForTesting()); |
| + worker_thread->WakeUp(); |
| + delegate->WaitForWorkToRun(); |
| + delegate->WaitForDetachRequest(); |
| + ASSERT_TRUE(worker_thread->WorkerAliveForTesting()); |
| + worker_thread->JoinForTesting(); |
| +} |
| + |
| } // namespace |
| } // namespace internal |
| } // namespace base |