Chromium Code Reviews| OLD | NEW |
|---|---|
| 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_thread.h" | 5 #include "base/task_scheduler/scheduler_worker_thread.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/synchronization/condition_variable.h" | 16 #include "base/synchronization/condition_variable.h" |
| 17 #include "base/task_scheduler/delayed_task_manager.h" | |
| 18 #include "base/task_scheduler/priority_queue.h" | |
| 17 #include "base/task_scheduler/scheduler_lock.h" | 19 #include "base/task_scheduler/scheduler_lock.h" |
| 18 #include "base/task_scheduler/sequence.h" | 20 #include "base/task_scheduler/sequence.h" |
| 19 #include "base/task_scheduler/task.h" | 21 #include "base/task_scheduler/task.h" |
| 20 #include "base/task_scheduler/task_tracker.h" | 22 #include "base/task_scheduler/task_tracker.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
| 22 | 24 |
| 23 namespace base { | 25 namespace base { |
| 24 namespace internal { | 26 namespace internal { |
| 25 namespace { | 27 namespace { |
| 26 | 28 |
| 27 const size_t kNumSequencesPerTest = 150; | |
| 28 | |
| 29 // The test parameter is the number of Tasks per Sequence returned by GetWork(). | 29 // The test parameter is the number of Tasks per Sequence returned by GetWork(). |
| 30 class TaskSchedulerWorkerThreadTest : public testing::TestWithParam<size_t>, | 30 class TaskSchedulerWorkerThreadDelegateWorkTest |
| 31 public SchedulerWorkerThread::Delegate { | 31 : public testing::TestWithParam<size_t>, |
| 32 public SchedulerWorkerThread::Delegate { | |
| 32 protected: | 33 protected: |
| 33 TaskSchedulerWorkerThreadTest() | 34 TaskSchedulerWorkerThreadDelegateWorkTest() |
| 34 : main_entry_called_(true, false), | 35 : delayed_task_manager_(Bind(&DoNothing)), |
| 36 main_entry_called_(true, false), | |
| 35 num_get_work_cv_(lock_.CreateConditionVariable()) {} | 37 num_get_work_cv_(lock_.CreateConditionVariable()) {} |
| 36 | 38 |
| 37 void SetUp() override { | 39 void SetUp() override { |
| 38 worker_thread_ = SchedulerWorkerThread::CreateSchedulerWorkerThread( | 40 worker_thread_ = SchedulerWorkerThread::CreateSchedulerWorkerThread( |
| 39 ThreadPriority::NORMAL, this, &task_tracker_); | 41 ThreadPriority::NORMAL, this, &task_tracker_, &delayed_task_manager_, |
| 42 &dummy_priority_queue_); | |
| 40 ASSERT_TRUE(worker_thread_); | 43 ASSERT_TRUE(worker_thread_); |
| 41 main_entry_called_.Wait(); | 44 main_entry_called_.Wait(); |
| 42 } | 45 } |
| 43 | 46 |
| 44 void TearDown() override { | 47 void TearDown() override { |
| 45 worker_thread_->JoinForTesting(); | 48 worker_thread_->JoinForTesting(); |
| 46 } | 49 } |
| 47 | 50 |
| 48 size_t TasksPerSequence() const { return GetParam(); } | 51 size_t TasksPerSequence() const { return GetParam(); } |
| 49 | 52 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 73 std::vector<scoped_refptr<Sequence>> CreatedSequences() { | 76 std::vector<scoped_refptr<Sequence>> CreatedSequences() { |
| 74 AutoSchedulerLock auto_lock(lock_); | 77 AutoSchedulerLock auto_lock(lock_); |
| 75 return created_sequences_; | 78 return created_sequences_; |
| 76 } | 79 } |
| 77 | 80 |
| 78 std::vector<scoped_refptr<Sequence>> EnqueuedSequences() { | 81 std::vector<scoped_refptr<Sequence>> EnqueuedSequences() { |
| 79 AutoSchedulerLock auto_lock(lock_); | 82 AutoSchedulerLock auto_lock(lock_); |
| 80 return enqueued_sequences_; | 83 return enqueued_sequences_; |
| 81 } | 84 } |
| 82 | 85 |
| 86 const size_t kNumSequencesPerTest = 150; | |
|
gab
2016/04/18 18:04:02
s/const/constexpr/ (see chromium-dev about new C++
fdoray
2016/04/18 19:04:50
Done.
| |
| 87 | |
| 83 std::unique_ptr<SchedulerWorkerThread> worker_thread_; | 88 std::unique_ptr<SchedulerWorkerThread> worker_thread_; |
| 84 | 89 |
| 85 private: | 90 private: |
| 86 // SchedulerWorkerThread::Delegate: | 91 // SchedulerWorkerThread::Delegate: |
| 87 void OnMainEntry() override { | 92 void OnMainEntry() override { |
| 88 // Without this |auto_lock|, OnMainEntry() could be called twice without | 93 // Without this |auto_lock|, OnMainEntry() could be called twice without |
| 89 // generating an error. | 94 // generating an error. |
| 90 AutoSchedulerLock auto_lock(lock_); | 95 AutoSchedulerLock auto_lock(lock_); |
| 91 EXPECT_FALSE(main_entry_called_.IsSignaled()); | 96 EXPECT_FALSE(main_entry_called_.IsSignaled()); |
| 92 main_entry_called_.Signal(); | 97 main_entry_called_.Signal(); |
| 93 } | 98 } |
| 94 | 99 |
| 95 scoped_refptr<Sequence> GetWork( | 100 scoped_refptr<Sequence> GetWork(SchedulerWorkerThread* worker_thread, |
| 96 SchedulerWorkerThread* worker_thread) override { | 101 PriorityQueue* single_threaded_priority_queue, |
| 102 bool* is_single_threaded_sequence) override { | |
| 97 EXPECT_EQ(worker_thread_.get(), worker_thread); | 103 EXPECT_EQ(worker_thread_.get(), worker_thread); |
| 98 | 104 |
| 99 { | 105 { |
| 100 AutoSchedulerLock auto_lock(lock_); | 106 AutoSchedulerLock auto_lock(lock_); |
| 101 | 107 |
| 102 // Increment the number of times that this method has been called. | 108 // Increment the number of times that this method has been called. |
| 103 ++num_get_work_; | 109 ++num_get_work_; |
| 104 num_get_work_cv_->Signal(); | 110 num_get_work_cv_->Signal(); |
| 105 | 111 |
| 106 // Verify that this method isn't called more times than expected. | 112 // Verify that this method isn't called more times than expected. |
| 107 EXPECT_LE(num_get_work_, max_get_work_); | 113 EXPECT_LE(num_get_work_, max_get_work_); |
| 108 | 114 |
| 109 // Check if a Sequence should be returned. | 115 // Check if a Sequence should be returned. |
| 110 if (num_sequences_to_create_ == 0) | 116 if (num_sequences_to_create_ == 0) |
| 111 return nullptr; | 117 return nullptr; |
| 112 --num_sequences_to_create_; | 118 --num_sequences_to_create_; |
| 113 } | 119 } |
| 114 | 120 |
| 115 // Create a Sequence with TasksPerSequence() Tasks. | 121 // Create a Sequence with TasksPerSequence() Tasks. |
| 116 scoped_refptr<Sequence> sequence(new Sequence); | 122 scoped_refptr<Sequence> sequence(new Sequence); |
| 117 for (size_t i = 0; i < TasksPerSequence(); ++i) { | 123 for (size_t i = 0; i < TasksPerSequence(); ++i) { |
| 118 std::unique_ptr<Task> task(new Task( | 124 std::unique_ptr<Task> task(new Task( |
| 119 FROM_HERE, Bind(&TaskSchedulerWorkerThreadTest::RunTaskCallback, | 125 FROM_HERE, |
| 120 Unretained(this)), | 126 Bind(&TaskSchedulerWorkerThreadDelegateWorkTest::RunTaskCallback, |
| 127 Unretained(this)), | |
| 121 TaskTraits())); | 128 TaskTraits())); |
| 122 EXPECT_TRUE(task_tracker_.WillPostTask(task.get())); | 129 EXPECT_TRUE(task_tracker_.WillPostTask(task.get())); |
| 123 sequence->PushTask(std::move(task)); | 130 sequence->PushTask(std::move(task)); |
| 124 } | 131 } |
| 125 | 132 |
| 126 { | 133 { |
| 127 // Add the Sequence to the vector of created Sequences. | 134 // Add the Sequence to the vector of created Sequences. |
| 128 AutoSchedulerLock auto_lock(lock_); | 135 AutoSchedulerLock auto_lock(lock_); |
| 129 created_sequences_.push_back(sequence); | 136 created_sequences_.push_back(sequence); |
| 130 } | 137 } |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 152 EXPECT_LE(enqueued_sequences_.size(), created_sequences_.size()); | 159 EXPECT_LE(enqueued_sequences_.size(), created_sequences_.size()); |
| 153 } | 160 } |
| 154 | 161 |
| 155 void RunTaskCallback() { | 162 void RunTaskCallback() { |
| 156 AutoSchedulerLock auto_lock(lock_); | 163 AutoSchedulerLock auto_lock(lock_); |
| 157 ++num_run_tasks_; | 164 ++num_run_tasks_; |
| 158 EXPECT_LE(num_run_tasks_, created_sequences_.size()); | 165 EXPECT_LE(num_run_tasks_, created_sequences_.size()); |
| 159 } | 166 } |
| 160 | 167 |
| 161 TaskTracker task_tracker_; | 168 TaskTracker task_tracker_; |
| 169 DelayedTaskManager delayed_task_manager_; | |
| 170 PriorityQueue dummy_priority_queue_; | |
| 162 | 171 |
| 163 // Synchronizes access to all members below. | 172 // Synchronizes access to all members below. |
| 164 mutable SchedulerLock lock_; | 173 mutable SchedulerLock lock_; |
| 165 | 174 |
| 166 // Signaled once OnMainEntry() has been called. | 175 // Signaled once OnMainEntry() has been called. |
| 167 WaitableEvent main_entry_called_; | 176 WaitableEvent main_entry_called_; |
| 168 | 177 |
| 169 // Number of Sequences that should be created by GetWork(). When this | 178 // Number of Sequences that should be created by GetWork(). When this |
| 170 // is 0, GetWork() returns nullptr. | 179 // is 0, GetWork() returns nullptr. |
| 171 size_t num_sequences_to_create_ = 0; | 180 size_t num_sequences_to_create_ = 0; |
| 172 | 181 |
| 173 // Number of times that GetWork() has been called. | 182 // Number of times that GetWork() has been called. |
| 174 size_t num_get_work_ = 0; | 183 size_t num_get_work_ = 0; |
| 175 | 184 |
| 176 // Maximum number of times that GetWork() can be called. | 185 // Maximum number of times that GetWork() can be called. |
| 177 size_t max_get_work_ = 0; | 186 size_t max_get_work_ = 0; |
| 178 | 187 |
| 179 // Condition variable signaled when |num_get_work_| is incremented. | 188 // Condition variable signaled when |num_get_work_| is incremented. |
| 180 std::unique_ptr<ConditionVariable> num_get_work_cv_; | 189 std::unique_ptr<ConditionVariable> num_get_work_cv_; |
| 181 | 190 |
| 182 // Sequences created by GetWork(). | 191 // Sequences created by GetWork(). |
| 183 std::vector<scoped_refptr<Sequence>> created_sequences_; | 192 std::vector<scoped_refptr<Sequence>> created_sequences_; |
| 184 | 193 |
| 185 // Sequences passed to EnqueueSequence(). | 194 // Sequences passed to EnqueueSequence(). |
| 186 std::vector<scoped_refptr<Sequence>> enqueued_sequences_; | 195 std::vector<scoped_refptr<Sequence>> enqueued_sequences_; |
| 187 | 196 |
| 188 // Number of times that RunTaskCallback() has been called. | 197 // Number of times that RunTaskCallback() has been called. |
| 189 size_t num_run_tasks_ = 0; | 198 size_t num_run_tasks_ = 0; |
| 190 | 199 |
| 191 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerThreadTest); | 200 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerThreadDelegateWorkTest); |
| 192 }; | 201 }; |
| 193 | 202 |
| 194 // Verify that when GetWork() continuously returns Sequences, all Tasks in these | 203 // Verify that when GetWork() continuously returns Sequences, all Tasks in these |
| 195 // Sequences run successfully. The test wakes up the SchedulerWorkerThread once. | 204 // Sequences run successfully. The test wakes up the SchedulerWorkerThread once. |
| 196 TEST_P(TaskSchedulerWorkerThreadTest, ContinuousWork) { | 205 TEST_P(TaskSchedulerWorkerThreadDelegateWorkTest, ContinuousWork) { |
| 197 // Set GetWork() to return |kNumSequencesPerTest| Sequences before starting to | 206 // Set GetWork() to return |kNumSequencesPerTest| Sequences before starting to |
| 198 // return nullptr. | 207 // return nullptr. |
| 199 SetNumSequencesToCreate(kNumSequencesPerTest); | 208 SetNumSequencesToCreate(kNumSequencesPerTest); |
| 200 | 209 |
| 201 // Expect |kNumSequencesPerTest| calls to GetWork() in which it returns a | 210 // Expect |kNumSequencesPerTest| calls to GetWork() in which it returns a |
| 202 // Sequence and one call in which its returns nullptr. | 211 // Sequence and one call in which its returns nullptr. |
| 203 const size_t kExpectedNumGetWork = kNumSequencesPerTest + 1; | 212 const size_t kExpectedNumGetWork = kNumSequencesPerTest + 1; |
| 204 SetMaxGetWork(kExpectedNumGetWork); | 213 SetMaxGetWork(kExpectedNumGetWork); |
| 205 | 214 |
| 206 // Wake up |worker_thread_| and wait until GetWork() has been invoked the | 215 // Wake up |worker_thread_| and wait until GetWork() has been invoked the |
| 207 // expected amount of times. | 216 // expected amount of times. |
| 208 worker_thread_->WakeUp(); | 217 worker_thread_->WakeUp(); |
| 209 WaitForNumGetWork(kExpectedNumGetWork); | 218 WaitForNumGetWork(kExpectedNumGetWork); |
| 210 | 219 |
| 211 // All tasks should have run. | 220 // All tasks should have run. |
| 212 EXPECT_EQ(kNumSequencesPerTest, NumRunTasks()); | 221 EXPECT_EQ(kNumSequencesPerTest, NumRunTasks()); |
| 213 | 222 |
| 214 // If Sequences returned by GetWork() contain more than one Task, they aren't | 223 // If Sequences returned by GetWork() contain more than one Task, they aren't |
| 215 // empty after the worker thread pops Tasks from them and thus should be | 224 // empty after the worker thread pops Tasks from them and thus should be |
| 216 // returned to EnqueueSequence(). | 225 // returned to EnqueueSequence(). |
| 217 if (TasksPerSequence() > 1) | 226 if (TasksPerSequence() > 1) |
| 218 EXPECT_EQ(CreatedSequences(), EnqueuedSequences()); | 227 EXPECT_EQ(CreatedSequences(), EnqueuedSequences()); |
| 219 else | 228 else |
| 220 EXPECT_TRUE(EnqueuedSequences().empty()); | 229 EXPECT_TRUE(EnqueuedSequences().empty()); |
| 221 } | 230 } |
| 222 | 231 |
| 223 // Verify that when GetWork() alternates between returning a Sequence and | 232 // Verify that when GetWork() alternates between returning a Sequence and |
| 224 // returning nullptr, all Tasks in the returned Sequences run successfully. The | 233 // returning nullptr, all Tasks in the returned Sequences run successfully. The |
| 225 // test wakes up the SchedulerWorkerThread once for each Sequence. | 234 // test wakes up the SchedulerWorkerThread once for each Sequence. |
| 226 TEST_P(TaskSchedulerWorkerThreadTest, IntermittentWork) { | 235 TEST_P(TaskSchedulerWorkerThreadDelegateWorkTest, IntermittentWork) { |
| 227 for (size_t i = 0; i < kNumSequencesPerTest; ++i) { | 236 for (size_t i = 0; i < kNumSequencesPerTest; ++i) { |
| 228 // Set GetWork() to return 1 Sequence before starting to return | 237 // Set GetWork() to return 1 Sequence before starting to return |
| 229 // nullptr. | 238 // nullptr. |
| 230 SetNumSequencesToCreate(1); | 239 SetNumSequencesToCreate(1); |
| 231 | 240 |
| 232 // Expect |i + 1| calls to GetWork() in which it returns a Sequence and | 241 // Expect |i + 1| calls to GetWork() in which it returns a Sequence and |
| 233 // |i + 1| calls in which it returns nullptr. | 242 // |i + 1| calls in which it returns nullptr. |
| 234 const size_t expected_num_get_work = 2 * (i + 1); | 243 const size_t expected_num_get_work = 2 * (i + 1); |
| 235 SetMaxGetWork(expected_num_get_work); | 244 SetMaxGetWork(expected_num_get_work); |
| 236 | 245 |
| 237 // Wake up |worker_thread_| and wait until GetWork() has been invoked | 246 // Wake up |worker_thread_| and wait until GetWork() has been invoked |
| 238 // the expected amount of times. | 247 // the expected amount of times. |
| 239 worker_thread_->WakeUp(); | 248 worker_thread_->WakeUp(); |
| 240 WaitForNumGetWork(expected_num_get_work); | 249 WaitForNumGetWork(expected_num_get_work); |
| 241 | 250 |
| 242 // The Task should have run | 251 // The Task should have run |
| 243 EXPECT_EQ(i + 1, NumRunTasks()); | 252 EXPECT_EQ(i + 1, NumRunTasks()); |
| 244 | 253 |
| 245 // If Sequences returned by GetWork() contain more than one Task, they | 254 // If Sequences returned by GetWork() contain more than one Task, they |
| 246 // aren't empty after the worker thread pops Tasks from them and thus should | 255 // aren't empty after the worker thread pops Tasks from them and thus should |
| 247 // be returned to EnqueueSequence(). | 256 // be returned to EnqueueSequence(). |
| 248 if (TasksPerSequence() > 1) | 257 if (TasksPerSequence() > 1) |
| 249 EXPECT_EQ(CreatedSequences(), EnqueuedSequences()); | 258 EXPECT_EQ(CreatedSequences(), EnqueuedSequences()); |
| 250 else | 259 else |
| 251 EXPECT_TRUE(EnqueuedSequences().empty()); | 260 EXPECT_TRUE(EnqueuedSequences().empty()); |
| 252 } | 261 } |
| 253 } | 262 } |
| 254 | 263 |
| 255 INSTANTIATE_TEST_CASE_P(OneTaskPerSequence, | 264 INSTANTIATE_TEST_CASE_P(OneTaskPerSequence, |
| 256 TaskSchedulerWorkerThreadTest, | 265 TaskSchedulerWorkerThreadDelegateWorkTest, |
| 257 ::testing::Values(1)); | 266 ::testing::Values(1)); |
| 258 INSTANTIATE_TEST_CASE_P(TwoTasksPerSequence, | 267 INSTANTIATE_TEST_CASE_P(TwoTasksPerSequence, |
| 259 TaskSchedulerWorkerThreadTest, | 268 TaskSchedulerWorkerThreadDelegateWorkTest, |
| 260 ::testing::Values(2)); | 269 ::testing::Values(2)); |
| 261 | 270 |
| 271 class TaskSchedulerWorkerThreadSingleThreadedWorkTest | |
| 272 : public testing::Test, | |
| 273 public SchedulerWorkerThread::Delegate { | |
| 274 protected: | |
| 275 TaskSchedulerWorkerThreadSingleThreadedWorkTest() | |
| 276 : delayed_task_manager_(Bind(&DoNothing)), | |
| 277 num_run_tasks_cv_(lock_.CreateConditionVariable()) {} | |
| 278 | |
| 279 void SetUp() override { | |
| 280 worker_thread_ = SchedulerWorkerThread::CreateSchedulerWorkerThread( | |
| 281 ThreadPriority::NORMAL, this, &task_tracker_, &delayed_task_manager_, | |
| 282 &dummy_priority_queue_); | |
| 283 ASSERT_TRUE(worker_thread_); | |
| 284 } | |
| 285 | |
| 286 void TearDown() override { worker_thread_->JoinForTesting(); } | |
| 287 | |
| 288 void PostTestTask(scoped_refptr<TaskRunner> task_runner) { | |
| 289 Closure closure; | |
| 290 { | |
| 291 AutoSchedulerLock auto_lock(lock_); | |
| 292 closure = Bind( | |
| 293 &TaskSchedulerWorkerThreadSingleThreadedWorkTest::RunTaskCallback, | |
| 294 Unretained(this), num_posted_tasks_++, task_runner); | |
|
gab
2016/04/18 18:04:02
Only need to lock to get index from |num_posted_ta
fdoray
2016/04/18 19:04:50
Done.
| |
| 295 } | |
| 296 task_runner->PostTask(FROM_HERE, closure); | |
| 297 } | |
| 298 | |
| 299 void WaitForAllTasksToRun() { | |
| 300 AutoSchedulerLock auto_lock(lock_); | |
| 301 while (num_run_tasks_ < num_posted_tasks_) | |
| 302 num_run_tasks_cv_->Wait(); | |
| 303 } | |
| 304 | |
| 305 const size_t kNumTasksPerTest = 150; | |
| 306 | |
| 307 std::unique_ptr<SchedulerWorkerThread> worker_thread_; | |
| 308 | |
| 309 private: | |
| 310 // SchedulerWorkerThread::Delegate: | |
| 311 void OnMainEntry() override {} | |
| 312 | |
| 313 scoped_refptr<Sequence> GetWork(SchedulerWorkerThread* worker_thread, | |
| 314 PriorityQueue* single_threaded_priority_queue, | |
| 315 bool* is_single_threaded_sequence) override { | |
| 316 EXPECT_EQ(worker_thread_.get(), worker_thread); | |
| 317 | |
| 318 // Return a Sequence from |single_threaded_priority_queue| or nullptr if it | |
| 319 // is empty. | |
| 320 auto transaction = single_threaded_priority_queue->BeginTransaction(); | |
| 321 auto sequence = transaction->Peek().sequence; | |
| 322 if (!sequence) | |
| 323 return nullptr; | |
| 324 *is_single_threaded_sequence = true; | |
| 325 transaction->Pop(); | |
| 326 return sequence; | |
| 327 } | |
| 328 | |
| 329 void EnqueueSequence(scoped_refptr<Sequence> sequence) override { | |
| 330 ADD_FAILURE() << "EnqueueSequence shouldn't be called in a test that only " | |
| 331 "posts single-threaded Tasks."; | |
| 332 } | |
| 333 | |
| 334 void RunTaskCallback(size_t index, scoped_refptr<TaskRunner> task_runner) { | |
| 335 AutoSchedulerLock auto_lock(lock_); | |
| 336 | |
| 337 EXPECT_TRUE(task_runner->RunsTasksOnCurrentThread()); | |
| 338 | |
| 339 // Verify that tasks run in posting order. | |
| 340 EXPECT_EQ(num_run_tasks_, index); | |
| 341 | |
| 342 // Verify that we don't run more tasks than posted. | |
| 343 ++num_run_tasks_; | |
| 344 EXPECT_LE(num_run_tasks_, num_posted_tasks_); | |
| 345 | |
| 346 num_run_tasks_cv_->Signal(); | |
| 347 } | |
| 348 | |
| 349 TaskTracker task_tracker_; | |
| 350 DelayedTaskManager delayed_task_manager_; | |
| 351 PriorityQueue dummy_priority_queue_; | |
| 352 | |
| 353 // Synchronizes access to all members below. | |
| 354 mutable SchedulerLock lock_; | |
| 355 | |
| 356 // Number of tasks posted by PostTestTask(). | |
| 357 size_t num_posted_tasks_ = 0; | |
| 358 | |
| 359 // Number of times that RunTaskCallback() has been called. | |
| 360 size_t num_run_tasks_ = 0; | |
| 361 | |
| 362 // Condition variable signaled when |num_run_tasks_| is incremented. | |
| 363 std::unique_ptr<ConditionVariable> num_run_tasks_cv_; | |
| 364 | |
| 365 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerThreadSingleThreadedWorkTest); | |
| 366 }; | |
| 367 | |
| 368 TEST_F(TaskSchedulerWorkerThreadSingleThreadedWorkTest, ContinuousWork) { | |
| 369 auto task_runner = worker_thread_->CreateTaskRunnerWithTraits(TaskTraits()); | |
| 370 EXPECT_FALSE(task_runner->RunsTasksOnCurrentThread()); | |
| 371 | |
| 372 for (size_t i = 0; i < kNumTasksPerTest; ++i) | |
| 373 PostTestTask(task_runner); | |
| 374 WaitForAllTasksToRun(); | |
| 375 } | |
| 376 | |
| 377 TEST_F(TaskSchedulerWorkerThreadSingleThreadedWorkTest, IntermittentWork) { | |
| 378 auto task_runner = worker_thread_->CreateTaskRunnerWithTraits(TaskTraits()); | |
| 379 EXPECT_FALSE(task_runner->RunsTasksOnCurrentThread()); | |
| 380 | |
| 381 for (size_t i = 0; i < kNumTasksPerTest; ++i) { | |
| 382 PostTestTask(task_runner); | |
| 383 WaitForAllTasksToRun(); | |
| 384 } | |
| 385 } | |
| 386 | |
| 262 } // namespace | 387 } // namespace |
| 263 } // namespace internal | 388 } // namespace internal |
| 264 } // namespace base | 389 } // namespace base |
| OLD | NEW |