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

Unified Diff: base/task_scheduler/scheduler_worker_thread_unittest.cc

Issue 2044023003: Virtualize The Existence of a Scheduler Worker Thread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@detach
Patch Set: CR Feedback gab@ Created 4 years, 6 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 side-by-side diff with in-line comments
Download patch
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..927f3e56ec41030a70775f16ef07852d03342e89 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::InitialState::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_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)
+ override {
+ // Sends one item of work to signal work_processed_. On subsequent calls,
gab 2016/06/13 19:23:06 |work_processed_|
robliao 2016/06/13 23:23:28 Done.
+ // send nullptr to indicate there's no more work to be done.
+ 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() <<
gab 2016/06/13 19:23:06 Actually, in tests, prefer ADD_FAILURE() to NOTREA
robliao 2016/06/13 23:23:28 Done.
+ "GetWork() returns a sequence of one, so there's nothing to reenqueue.";
+ }
+
+ 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 ResetState() {
+ work_requested_ = false;
+ work_processed_.Reset();
+ detach_requested_.Reset();
+ }
+
+ void set_can_detach(bool can_detach) { can_detach_ = can_detach; }
+
+ private:
+ bool work_requested_ = false;
+ bool can_detach_ = false;
+ 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::InitialState::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::InitialState::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->ResetState();
+ delegate->set_can_detach(false);
+ worker_thread->WakeUp();
+ delegate->WaitForWorkToRun();
+ delegate->WaitForDetachRequest();
+ PlatformThread::Sleep(TimeDelta::FromMilliseconds(50));
+ ASSERT_TRUE(worker_thread->WorkerAliveForTesting());
fdoray 2016/06/13 20:31:17 EXPECT_TRUE() We want JoinForTesting() to run even
robliao 2016/06/13 23:23:28 This needs to be an ASSERT. There's no thread to j
+ 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::InitialState::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

Powered by Google App Engine
This is Rietveld 408576698