| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/child/scheduler/task_queue_manager.h" | |
| 6 | |
| 7 #include "base/threading/thread.h" | |
| 8 #include "cc/test/ordered_simple_task_runner.h" | |
| 9 #include "cc/test/test_now_source.h" | |
| 10 #include "content/child/scheduler/nestable_task_runner_for_test.h" | |
| 11 #include "content/child/scheduler/scheduler_message_loop_delegate.h" | |
| 12 #include "content/child/scheduler/task_queue_selector.h" | |
| 13 #include "content/test/test_time_source.h" | |
| 14 #include "testing/gmock/include/gmock/gmock.h" | |
| 15 | |
| 16 using testing::ElementsAre; | |
| 17 using testing::_; | |
| 18 | |
| 19 namespace content { | |
| 20 namespace { | |
| 21 | |
| 22 class SelectorForTest : public TaskQueueSelector { | |
| 23 public: | |
| 24 ~SelectorForTest() override {} | |
| 25 | |
| 26 virtual void AppendQueueToService(size_t queue_index) = 0; | |
| 27 | |
| 28 virtual const std::vector<const base::TaskQueue*>& work_queues() = 0; | |
| 29 | |
| 30 void AsValueInto(base::trace_event::TracedValue* state) const override {} | |
| 31 }; | |
| 32 | |
| 33 // Always selects queue 0. | |
| 34 class AutomaticSelectorForTest : public SelectorForTest { | |
| 35 public: | |
| 36 AutomaticSelectorForTest() {} | |
| 37 ~AutomaticSelectorForTest() override {} | |
| 38 | |
| 39 void RegisterWorkQueues( | |
| 40 const std::vector<const base::TaskQueue*>& work_queues) override { | |
| 41 work_queues_ = work_queues; | |
| 42 } | |
| 43 | |
| 44 bool SelectWorkQueueToService(size_t* out_queue_index) override { | |
| 45 for (size_t i = 0; i < work_queues_.size(); i++) { | |
| 46 if (!work_queues_[i]->empty()) { | |
| 47 *out_queue_index = i; | |
| 48 return true; | |
| 49 } | |
| 50 } | |
| 51 return false; | |
| 52 } | |
| 53 | |
| 54 void AppendQueueToService(size_t queue_index) override { | |
| 55 DCHECK(false) << "Not supported"; | |
| 56 } | |
| 57 | |
| 58 const std::vector<const base::TaskQueue*>& work_queues() override { | |
| 59 return work_queues_; | |
| 60 } | |
| 61 | |
| 62 void SetTaskQueueSelectorObserver(Observer* observer) override { | |
| 63 } | |
| 64 | |
| 65 private: | |
| 66 std::vector<const base::TaskQueue*> work_queues_; | |
| 67 | |
| 68 DISALLOW_COPY_AND_ASSIGN(AutomaticSelectorForTest); | |
| 69 }; | |
| 70 | |
| 71 class ExplicitSelectorForTest : public SelectorForTest { | |
| 72 public: | |
| 73 ExplicitSelectorForTest() {} | |
| 74 ~ExplicitSelectorForTest() override {} | |
| 75 | |
| 76 void RegisterWorkQueues( | |
| 77 const std::vector<const base::TaskQueue*>& work_queues) override { | |
| 78 work_queues_ = work_queues; | |
| 79 } | |
| 80 | |
| 81 bool SelectWorkQueueToService(size_t* out_queue_index) override { | |
| 82 if (queues_to_service_.empty()) | |
| 83 return false; | |
| 84 *out_queue_index = queues_to_service_.front(); | |
| 85 queues_to_service_.pop_front(); | |
| 86 return true; | |
| 87 } | |
| 88 | |
| 89 void AppendQueueToService(size_t queue_index) override { | |
| 90 queues_to_service_.push_back(queue_index); | |
| 91 } | |
| 92 | |
| 93 const std::vector<const base::TaskQueue*>& work_queues() override { | |
| 94 return work_queues_; | |
| 95 } | |
| 96 | |
| 97 void SetTaskQueueSelectorObserver(Observer* observer) override { | |
| 98 } | |
| 99 | |
| 100 private: | |
| 101 std::deque<size_t> queues_to_service_; | |
| 102 std::vector<const base::TaskQueue*> work_queues_; | |
| 103 | |
| 104 DISALLOW_COPY_AND_ASSIGN(ExplicitSelectorForTest); | |
| 105 }; | |
| 106 | |
| 107 class TaskQueueManagerTest : public testing::Test { | |
| 108 public: | |
| 109 void DeleteTaskQueueManager() { | |
| 110 manager_.reset(); | |
| 111 } | |
| 112 | |
| 113 protected: | |
| 114 enum class SelectorType { | |
| 115 Automatic, | |
| 116 Explicit, | |
| 117 }; | |
| 118 | |
| 119 void Initialize(size_t num_queues, SelectorType type) { | |
| 120 now_src_ = cc::TestNowSource::Create(1000); | |
| 121 test_task_runner_ = | |
| 122 make_scoped_refptr(new cc::OrderedSimpleTaskRunner(now_src_, false)); | |
| 123 selector_ = make_scoped_ptr(createSelectorForTest(type)); | |
| 124 manager_ = make_scoped_ptr(new TaskQueueManager( | |
| 125 num_queues, NestableTaskRunnerForTest::Create(test_task_runner_.get()), | |
| 126 selector_.get(), "test.scheduler")); | |
| 127 manager_->SetTimeSourceForTesting( | |
| 128 make_scoped_ptr(new TestTimeSource(now_src_))); | |
| 129 | |
| 130 EXPECT_EQ(num_queues, selector_->work_queues().size()); | |
| 131 } | |
| 132 | |
| 133 void InitializeWithRealMessageLoop(size_t num_queues, SelectorType type) { | |
| 134 message_loop_.reset(new base::MessageLoop()); | |
| 135 selector_ = make_scoped_ptr(createSelectorForTest(type)); | |
| 136 manager_ = make_scoped_ptr(new TaskQueueManager( | |
| 137 num_queues, SchedulerMessageLoopDelegate::Create(message_loop_.get()), | |
| 138 selector_.get(), "test.scheduler")); | |
| 139 EXPECT_EQ(num_queues, selector_->work_queues().size()); | |
| 140 } | |
| 141 | |
| 142 SelectorForTest* createSelectorForTest(SelectorType type) { | |
| 143 switch (type) { | |
| 144 case SelectorType::Automatic: | |
| 145 return new AutomaticSelectorForTest(); | |
| 146 | |
| 147 case SelectorType::Explicit: | |
| 148 return new ExplicitSelectorForTest(); | |
| 149 } | |
| 150 | |
| 151 return nullptr; | |
| 152 } | |
| 153 | |
| 154 scoped_refptr<cc::TestNowSource> now_src_; | |
| 155 scoped_refptr<cc::OrderedSimpleTaskRunner> test_task_runner_; | |
| 156 scoped_ptr<SelectorForTest> selector_; | |
| 157 scoped_ptr<TaskQueueManager> manager_; | |
| 158 scoped_ptr<base::MessageLoop> message_loop_; | |
| 159 }; | |
| 160 | |
| 161 void PostFromNestedRunloop(base::MessageLoop* message_loop, | |
| 162 base::SingleThreadTaskRunner* runner, | |
| 163 std::vector<std::pair<base::Closure, bool>>* tasks) { | |
| 164 base::MessageLoop::ScopedNestableTaskAllower allow(message_loop); | |
| 165 for (std::pair<base::Closure, bool>& pair : *tasks) { | |
| 166 if (pair.second) { | |
| 167 runner->PostTask(FROM_HERE, pair.first); | |
| 168 } else { | |
| 169 runner->PostNonNestableTask(FROM_HERE, pair.first); | |
| 170 } | |
| 171 } | |
| 172 message_loop->RunUntilIdle(); | |
| 173 } | |
| 174 | |
| 175 void TestTask(int value, std::vector<int>* out_result) { | |
| 176 out_result->push_back(value); | |
| 177 } | |
| 178 | |
| 179 TEST_F(TaskQueueManagerTest, SingleQueuePosting) { | |
| 180 Initialize(1u, SelectorType::Automatic); | |
| 181 | |
| 182 std::vector<int> run_order; | |
| 183 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 184 manager_->TaskRunnerForQueue(0); | |
| 185 | |
| 186 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 187 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
| 188 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
| 189 | |
| 190 test_task_runner_->RunUntilIdle(); | |
| 191 EXPECT_THAT(run_order, ElementsAre(1, 2, 3)); | |
| 192 } | |
| 193 | |
| 194 TEST_F(TaskQueueManagerTest, MultiQueuePosting) { | |
| 195 Initialize(3u, SelectorType::Explicit); | |
| 196 | |
| 197 std::vector<int> run_order; | |
| 198 scoped_refptr<base::SingleThreadTaskRunner> runners[3] = { | |
| 199 manager_->TaskRunnerForQueue(0), | |
| 200 manager_->TaskRunnerForQueue(1), | |
| 201 manager_->TaskRunnerForQueue(2)}; | |
| 202 | |
| 203 selector_->AppendQueueToService(0); | |
| 204 selector_->AppendQueueToService(1); | |
| 205 selector_->AppendQueueToService(2); | |
| 206 selector_->AppendQueueToService(0); | |
| 207 selector_->AppendQueueToService(1); | |
| 208 selector_->AppendQueueToService(2); | |
| 209 | |
| 210 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 211 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
| 212 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
| 213 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order)); | |
| 214 runners[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 5, &run_order)); | |
| 215 runners[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 6, &run_order)); | |
| 216 | |
| 217 test_task_runner_->RunUntilIdle(); | |
| 218 EXPECT_THAT(run_order, ElementsAre(1, 3, 5, 2, 4, 6)); | |
| 219 } | |
| 220 | |
| 221 void NopTask() { | |
| 222 } | |
| 223 | |
| 224 TEST_F(TaskQueueManagerTest, NowNotCalledWhenThereAreNoDelayedTasks) { | |
| 225 Initialize(3u, SelectorType::Explicit); | |
| 226 | |
| 227 scoped_refptr<cc::TestNowSource> now_src = cc::TestNowSource::Create(1000); | |
| 228 manager_->SetTimeSourceForTesting( | |
| 229 make_scoped_ptr(new TestTimeSource(now_src))); | |
| 230 | |
| 231 scoped_refptr<base::SingleThreadTaskRunner> runners[3] = { | |
| 232 manager_->TaskRunnerForQueue(0), | |
| 233 manager_->TaskRunnerForQueue(1), | |
| 234 manager_->TaskRunnerForQueue(2)}; | |
| 235 | |
| 236 selector_->AppendQueueToService(0); | |
| 237 selector_->AppendQueueToService(1); | |
| 238 selector_->AppendQueueToService(2); | |
| 239 selector_->AppendQueueToService(0); | |
| 240 selector_->AppendQueueToService(1); | |
| 241 selector_->AppendQueueToService(2); | |
| 242 | |
| 243 runners[0]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
| 244 runners[0]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
| 245 runners[1]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
| 246 runners[1]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
| 247 runners[2]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
| 248 runners[2]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
| 249 | |
| 250 test_task_runner_->RunUntilIdle(); | |
| 251 | |
| 252 EXPECT_EQ(0, now_src->NumNowCalls()); | |
| 253 } | |
| 254 | |
| 255 TEST_F(TaskQueueManagerTest, NonNestableTaskPosting) { | |
| 256 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
| 257 | |
| 258 std::vector<int> run_order; | |
| 259 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 260 manager_->TaskRunnerForQueue(0); | |
| 261 | |
| 262 runner->PostNonNestableTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 263 | |
| 264 message_loop_->RunUntilIdle(); | |
| 265 EXPECT_THAT(run_order, ElementsAre(1)); | |
| 266 } | |
| 267 | |
| 268 TEST_F(TaskQueueManagerTest, NonNestableTaskExecutesInExpectedOrder) { | |
| 269 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
| 270 | |
| 271 std::vector<int> run_order; | |
| 272 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 273 manager_->TaskRunnerForQueue(0); | |
| 274 | |
| 275 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 276 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
| 277 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
| 278 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order)); | |
| 279 runner->PostNonNestableTask(FROM_HERE, base::Bind(&TestTask, 5, &run_order)); | |
| 280 | |
| 281 message_loop_->RunUntilIdle(); | |
| 282 EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4, 5)); | |
| 283 } | |
| 284 | |
| 285 TEST_F(TaskQueueManagerTest, NonNestableTaskDoesntExecuteInNestedLoop) { | |
| 286 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
| 287 | |
| 288 std::vector<int> run_order; | |
| 289 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 290 manager_->TaskRunnerForQueue(0); | |
| 291 | |
| 292 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 293 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
| 294 | |
| 295 std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop; | |
| 296 tasks_to_post_from_nested_loop.push_back( | |
| 297 std::make_pair(base::Bind(&TestTask, 3, &run_order), false)); | |
| 298 tasks_to_post_from_nested_loop.push_back( | |
| 299 std::make_pair(base::Bind(&TestTask, 4, &run_order), true)); | |
| 300 tasks_to_post_from_nested_loop.push_back( | |
| 301 std::make_pair(base::Bind(&TestTask, 5, &run_order), true)); | |
| 302 | |
| 303 runner->PostTask( | |
| 304 FROM_HERE, base::Bind(&PostFromNestedRunloop, message_loop_.get(), runner, | |
| 305 base::Unretained(&tasks_to_post_from_nested_loop))); | |
| 306 | |
| 307 message_loop_->RunUntilIdle(); | |
| 308 // Note we expect task 3 to run last because it's non-nestable. | |
| 309 EXPECT_THAT(run_order, ElementsAre(1, 2, 4, 5, 3)); | |
| 310 } | |
| 311 | |
| 312 TEST_F(TaskQueueManagerTest, QueuePolling) { | |
| 313 Initialize(1u, SelectorType::Automatic); | |
| 314 | |
| 315 std::vector<int> run_order; | |
| 316 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 317 manager_->TaskRunnerForQueue(0); | |
| 318 | |
| 319 EXPECT_TRUE(manager_->IsQueueEmpty(0)); | |
| 320 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 321 EXPECT_FALSE(manager_->IsQueueEmpty(0)); | |
| 322 | |
| 323 test_task_runner_->RunUntilIdle(); | |
| 324 EXPECT_TRUE(manager_->IsQueueEmpty(0)); | |
| 325 } | |
| 326 | |
| 327 TEST_F(TaskQueueManagerTest, DelayedTaskPosting) { | |
| 328 Initialize(1u, SelectorType::Automatic); | |
| 329 | |
| 330 std::vector<int> run_order; | |
| 331 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 332 manager_->TaskRunnerForQueue(0); | |
| 333 | |
| 334 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | |
| 335 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
| 336 delay); | |
| 337 EXPECT_EQ(delay, test_task_runner_->DelayToNextTaskTime()); | |
| 338 EXPECT_TRUE(manager_->IsQueueEmpty(0)); | |
| 339 EXPECT_TRUE(run_order.empty()); | |
| 340 | |
| 341 // The task doesn't run before the delay has completed. | |
| 342 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(9)); | |
| 343 EXPECT_TRUE(run_order.empty()); | |
| 344 | |
| 345 // After the delay has completed, the task runs normally. | |
| 346 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1)); | |
| 347 EXPECT_THAT(run_order, ElementsAre(1)); | |
| 348 } | |
| 349 | |
| 350 TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_DecendingOrder) { | |
| 351 Initialize(1u, SelectorType::Automatic); | |
| 352 | |
| 353 std::vector<int> run_order; | |
| 354 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 355 manager_->TaskRunnerForQueue(0); | |
| 356 | |
| 357 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
| 358 base::TimeDelta::FromMilliseconds(10)); | |
| 359 | |
| 360 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order), | |
| 361 base::TimeDelta::FromMilliseconds(8)); | |
| 362 | |
| 363 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order), | |
| 364 base::TimeDelta::FromMilliseconds(5)); | |
| 365 | |
| 366 EXPECT_EQ(base::TimeDelta::FromMilliseconds(5), | |
| 367 test_task_runner_->DelayToNextTaskTime()); | |
| 368 | |
| 369 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5)); | |
| 370 EXPECT_THAT(run_order, ElementsAre(3)); | |
| 371 EXPECT_EQ(base::TimeDelta::FromMilliseconds(3), | |
| 372 test_task_runner_->DelayToNextTaskTime()); | |
| 373 | |
| 374 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(3)); | |
| 375 EXPECT_THAT(run_order, ElementsAre(3, 2)); | |
| 376 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2), | |
| 377 test_task_runner_->DelayToNextTaskTime()); | |
| 378 | |
| 379 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(2)); | |
| 380 EXPECT_THAT(run_order, ElementsAre(3, 2, 1)); | |
| 381 } | |
| 382 | |
| 383 TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_AscendingOrder) { | |
| 384 Initialize(1u, SelectorType::Automatic); | |
| 385 | |
| 386 std::vector<int> run_order; | |
| 387 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 388 manager_->TaskRunnerForQueue(0); | |
| 389 | |
| 390 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
| 391 base::TimeDelta::FromMilliseconds(1)); | |
| 392 | |
| 393 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order), | |
| 394 base::TimeDelta::FromMilliseconds(5)); | |
| 395 | |
| 396 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order), | |
| 397 base::TimeDelta::FromMilliseconds(10)); | |
| 398 | |
| 399 EXPECT_EQ(base::TimeDelta::FromMilliseconds(1), | |
| 400 test_task_runner_->DelayToNextTaskTime()); | |
| 401 | |
| 402 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1)); | |
| 403 EXPECT_THAT(run_order, ElementsAre(1)); | |
| 404 EXPECT_EQ(base::TimeDelta::FromMilliseconds(4), | |
| 405 test_task_runner_->DelayToNextTaskTime()); | |
| 406 | |
| 407 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(4)); | |
| 408 EXPECT_THAT(run_order, ElementsAre(1, 2)); | |
| 409 EXPECT_EQ(base::TimeDelta::FromMilliseconds(5), | |
| 410 test_task_runner_->DelayToNextTaskTime()); | |
| 411 | |
| 412 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5)); | |
| 413 EXPECT_THAT(run_order, ElementsAre(1, 2, 3)); | |
| 414 } | |
| 415 | |
| 416 TEST_F(TaskQueueManagerTest, PostDelayedTask_SharesUnderlyingDelayedTasks) { | |
| 417 Initialize(1u, SelectorType::Automatic); | |
| 418 | |
| 419 std::vector<int> run_order; | |
| 420 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 421 manager_->TaskRunnerForQueue(0); | |
| 422 | |
| 423 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | |
| 424 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
| 425 delay); | |
| 426 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order), | |
| 427 delay); | |
| 428 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order), | |
| 429 delay); | |
| 430 | |
| 431 EXPECT_EQ(1u, test_task_runner_->NumPendingTasks()); | |
| 432 } | |
| 433 | |
| 434 class TestObject { | |
| 435 public: | |
| 436 ~TestObject() { destructor_count_++; } | |
| 437 | |
| 438 void Run() { FAIL() << "TestObject::Run should not be called"; } | |
| 439 | |
| 440 static int destructor_count_; | |
| 441 }; | |
| 442 | |
| 443 int TestObject::destructor_count_ = 0; | |
| 444 | |
| 445 TEST_F(TaskQueueManagerTest, PendingDelayedTasksRemovedOnShutdown) { | |
| 446 Initialize(1u, SelectorType::Automatic); | |
| 447 | |
| 448 TestObject::destructor_count_ = 0; | |
| 449 | |
| 450 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 451 manager_->TaskRunnerForQueue(0); | |
| 452 | |
| 453 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | |
| 454 runner->PostDelayedTask( | |
| 455 FROM_HERE, base::Bind(&TestObject::Run, base::Owned(new TestObject())), | |
| 456 delay); | |
| 457 runner->PostTask( | |
| 458 FROM_HERE, base::Bind(&TestObject::Run, base::Owned(new TestObject()))); | |
| 459 | |
| 460 manager_.reset(); | |
| 461 | |
| 462 EXPECT_EQ(2, TestObject::destructor_count_); | |
| 463 } | |
| 464 | |
| 465 TEST_F(TaskQueueManagerTest, ManualPumping) { | |
| 466 Initialize(1u, SelectorType::Automatic); | |
| 467 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL); | |
| 468 | |
| 469 std::vector<int> run_order; | |
| 470 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 471 manager_->TaskRunnerForQueue(0); | |
| 472 | |
| 473 // Posting a task when pumping is disabled doesn't result in work getting | |
| 474 // posted. | |
| 475 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 476 EXPECT_FALSE(test_task_runner_->HasPendingTasks()); | |
| 477 | |
| 478 // However polling still works. | |
| 479 EXPECT_FALSE(manager_->IsQueueEmpty(0)); | |
| 480 | |
| 481 // After pumping the task runs normally. | |
| 482 manager_->PumpQueue(0); | |
| 483 EXPECT_TRUE(test_task_runner_->HasPendingTasks()); | |
| 484 test_task_runner_->RunUntilIdle(); | |
| 485 EXPECT_THAT(run_order, ElementsAre(1)); | |
| 486 } | |
| 487 | |
| 488 TEST_F(TaskQueueManagerTest, ManualPumpingToggle) { | |
| 489 Initialize(1u, SelectorType::Automatic); | |
| 490 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL); | |
| 491 | |
| 492 std::vector<int> run_order; | |
| 493 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 494 manager_->TaskRunnerForQueue(0); | |
| 495 | |
| 496 // Posting a task when pumping is disabled doesn't result in work getting | |
| 497 // posted. | |
| 498 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 499 EXPECT_FALSE(test_task_runner_->HasPendingTasks()); | |
| 500 | |
| 501 // When pumping is enabled the task runs normally. | |
| 502 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AUTO); | |
| 503 EXPECT_TRUE(test_task_runner_->HasPendingTasks()); | |
| 504 test_task_runner_->RunUntilIdle(); | |
| 505 EXPECT_THAT(run_order, ElementsAre(1)); | |
| 506 } | |
| 507 | |
| 508 TEST_F(TaskQueueManagerTest, DenyRunning) { | |
| 509 Initialize(1u, SelectorType::Explicit); | |
| 510 | |
| 511 std::vector<int> run_order; | |
| 512 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 513 manager_->TaskRunnerForQueue(0); | |
| 514 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 515 | |
| 516 // Since we haven't appended a work queue to be selected, the task doesn't | |
| 517 // run. | |
| 518 test_task_runner_->RunUntilIdle(); | |
| 519 EXPECT_TRUE(run_order.empty()); | |
| 520 | |
| 521 // Pumping the queue again with a selected work queue runs the task. | |
| 522 manager_->PumpQueue(0); | |
| 523 selector_->AppendQueueToService(0); | |
| 524 test_task_runner_->RunUntilIdle(); | |
| 525 EXPECT_THAT(run_order, ElementsAre(1)); | |
| 526 } | |
| 527 | |
| 528 TEST_F(TaskQueueManagerTest, ManualPumpingWithDelayedTask) { | |
| 529 Initialize(1u, SelectorType::Automatic); | |
| 530 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL); | |
| 531 | |
| 532 std::vector<int> run_order; | |
| 533 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 534 manager_->TaskRunnerForQueue(0); | |
| 535 | |
| 536 // Posting a delayed task when pumping will apply the delay, but won't cause | |
| 537 // work to executed afterwards. | |
| 538 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | |
| 539 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
| 540 delay); | |
| 541 | |
| 542 // After pumping but before the delay period has expired, task does not run. | |
| 543 manager_->PumpQueue(0); | |
| 544 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5)); | |
| 545 EXPECT_TRUE(run_order.empty()); | |
| 546 | |
| 547 // Once the delay has expired, pumping causes the task to run. | |
| 548 now_src_->AdvanceNow(base::TimeDelta::FromMilliseconds(5)); | |
| 549 manager_->PumpQueue(0); | |
| 550 EXPECT_TRUE(test_task_runner_->HasPendingTasks()); | |
| 551 test_task_runner_->RunPendingTasks(); | |
| 552 EXPECT_THAT(run_order, ElementsAre(1)); | |
| 553 } | |
| 554 | |
| 555 TEST_F(TaskQueueManagerTest, ManualPumpingWithMultipleDelayedTasks) { | |
| 556 Initialize(1u, SelectorType::Automatic); | |
| 557 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL); | |
| 558 | |
| 559 std::vector<int> run_order; | |
| 560 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 561 manager_->TaskRunnerForQueue(0); | |
| 562 | |
| 563 // Posting a delayed task when pumping will apply the delay, but won't cause | |
| 564 // work to executed afterwards. | |
| 565 base::TimeDelta delay1(base::TimeDelta::FromMilliseconds(1)); | |
| 566 base::TimeDelta delay2(base::TimeDelta::FromMilliseconds(10)); | |
| 567 base::TimeDelta delay3(base::TimeDelta::FromMilliseconds(20)); | |
| 568 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
| 569 delay1); | |
| 570 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order), | |
| 571 delay2); | |
| 572 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order), | |
| 573 delay3); | |
| 574 | |
| 575 now_src_->AdvanceNow(base::TimeDelta::FromMilliseconds(15)); | |
| 576 test_task_runner_->RunUntilIdle(); | |
| 577 EXPECT_TRUE(run_order.empty()); | |
| 578 | |
| 579 // Once the delay has expired, pumping causes the task to run. | |
| 580 manager_->PumpQueue(0); | |
| 581 test_task_runner_->RunUntilIdle(); | |
| 582 EXPECT_THAT(run_order, ElementsAre(1, 2)); | |
| 583 } | |
| 584 | |
| 585 TEST_F(TaskQueueManagerTest, DelayedTasksDontAutoRunWithManualPumping) { | |
| 586 Initialize(1u, SelectorType::Automatic); | |
| 587 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL); | |
| 588 | |
| 589 std::vector<int> run_order; | |
| 590 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 591 manager_->TaskRunnerForQueue(0); | |
| 592 | |
| 593 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | |
| 594 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
| 595 delay); | |
| 596 | |
| 597 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(10)); | |
| 598 EXPECT_TRUE(run_order.empty()); | |
| 599 } | |
| 600 | |
| 601 TEST_F(TaskQueueManagerTest, ManualPumpingWithNonEmptyWorkQueue) { | |
| 602 Initialize(1u, SelectorType::Automatic); | |
| 603 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL); | |
| 604 | |
| 605 std::vector<int> run_order; | |
| 606 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 607 manager_->TaskRunnerForQueue(0); | |
| 608 | |
| 609 // Posting two tasks and pumping twice should result in two tasks in the work | |
| 610 // queue. | |
| 611 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 612 manager_->PumpQueue(0); | |
| 613 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
| 614 manager_->PumpQueue(0); | |
| 615 | |
| 616 EXPECT_EQ(2u, selector_->work_queues()[0]->size()); | |
| 617 } | |
| 618 | |
| 619 void ReentrantTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner, | |
| 620 int countdown, | |
| 621 std::vector<int>* out_result) { | |
| 622 out_result->push_back(countdown); | |
| 623 if (--countdown) { | |
| 624 runner->PostTask(FROM_HERE, | |
| 625 Bind(&ReentrantTestTask, runner, countdown, out_result)); | |
| 626 } | |
| 627 } | |
| 628 | |
| 629 TEST_F(TaskQueueManagerTest, ReentrantPosting) { | |
| 630 Initialize(1u, SelectorType::Automatic); | |
| 631 | |
| 632 std::vector<int> run_order; | |
| 633 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 634 manager_->TaskRunnerForQueue(0); | |
| 635 | |
| 636 runner->PostTask(FROM_HERE, Bind(&ReentrantTestTask, runner, 3, &run_order)); | |
| 637 | |
| 638 test_task_runner_->RunUntilIdle(); | |
| 639 EXPECT_THAT(run_order, ElementsAre(3, 2, 1)); | |
| 640 } | |
| 641 | |
| 642 TEST_F(TaskQueueManagerTest, NoTasksAfterShutdown) { | |
| 643 Initialize(1u, SelectorType::Automatic); | |
| 644 | |
| 645 std::vector<int> run_order; | |
| 646 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 647 manager_->TaskRunnerForQueue(0); | |
| 648 | |
| 649 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 650 manager_.reset(); | |
| 651 selector_.reset(); | |
| 652 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 653 | |
| 654 test_task_runner_->RunUntilIdle(); | |
| 655 EXPECT_TRUE(run_order.empty()); | |
| 656 } | |
| 657 | |
| 658 void PostTaskToRunner(scoped_refptr<base::SingleThreadTaskRunner> runner, | |
| 659 std::vector<int>* run_order) { | |
| 660 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, run_order)); | |
| 661 } | |
| 662 | |
| 663 TEST_F(TaskQueueManagerTest, PostFromThread) { | |
| 664 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
| 665 | |
| 666 std::vector<int> run_order; | |
| 667 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 668 manager_->TaskRunnerForQueue(0); | |
| 669 | |
| 670 base::Thread thread("TestThread"); | |
| 671 thread.Start(); | |
| 672 thread.message_loop()->PostTask( | |
| 673 FROM_HERE, base::Bind(&PostTaskToRunner, runner, &run_order)); | |
| 674 thread.Stop(); | |
| 675 | |
| 676 message_loop_->RunUntilIdle(); | |
| 677 EXPECT_THAT(run_order, ElementsAre(1)); | |
| 678 } | |
| 679 | |
| 680 void RePostingTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner, | |
| 681 int* run_count) { | |
| 682 (*run_count)++; | |
| 683 runner->PostTask(FROM_HERE, Bind(&RePostingTestTask, | |
| 684 base::Unretained(runner.get()), run_count)); | |
| 685 } | |
| 686 | |
| 687 TEST_F(TaskQueueManagerTest, DoWorkCantPostItselfMultipleTimes) { | |
| 688 Initialize(1u, SelectorType::Automatic); | |
| 689 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 690 manager_->TaskRunnerForQueue(0); | |
| 691 | |
| 692 int run_count = 0; | |
| 693 runner->PostTask(FROM_HERE, | |
| 694 base::Bind(&RePostingTestTask, runner, &run_count)); | |
| 695 | |
| 696 test_task_runner_->RunPendingTasks(); | |
| 697 // NOTE without the executing_task_ check in MaybePostDoWorkOnMainRunner there | |
| 698 // will be two tasks here. | |
| 699 EXPECT_EQ(1u, test_task_runner_->NumPendingTasks()); | |
| 700 EXPECT_EQ(1, run_count); | |
| 701 } | |
| 702 | |
| 703 TEST_F(TaskQueueManagerTest, PostFromNestedRunloop) { | |
| 704 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
| 705 | |
| 706 std::vector<int> run_order; | |
| 707 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 708 manager_->TaskRunnerForQueue(0); | |
| 709 | |
| 710 std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop; | |
| 711 tasks_to_post_from_nested_loop.push_back( | |
| 712 std::make_pair(base::Bind(&TestTask, 1, &run_order), true)); | |
| 713 | |
| 714 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 0, &run_order)); | |
| 715 runner->PostTask( | |
| 716 FROM_HERE, base::Bind(&PostFromNestedRunloop, message_loop_.get(), runner, | |
| 717 base::Unretained(&tasks_to_post_from_nested_loop))); | |
| 718 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
| 719 | |
| 720 message_loop_->RunUntilIdle(); | |
| 721 | |
| 722 EXPECT_THAT(run_order, ElementsAre(0, 2, 1)); | |
| 723 } | |
| 724 | |
| 725 TEST_F(TaskQueueManagerTest, WorkBatching) { | |
| 726 Initialize(1u, SelectorType::Automatic); | |
| 727 | |
| 728 manager_->SetWorkBatchSize(2); | |
| 729 | |
| 730 std::vector<int> run_order; | |
| 731 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 732 manager_->TaskRunnerForQueue(0); | |
| 733 | |
| 734 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 735 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
| 736 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
| 737 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order)); | |
| 738 | |
| 739 // Running one task in the host message loop should cause two posted tasks to | |
| 740 // get executed. | |
| 741 EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u); | |
| 742 test_task_runner_->RunPendingTasks(); | |
| 743 EXPECT_THAT(run_order, ElementsAre(1, 2)); | |
| 744 | |
| 745 // The second task runs the remaining two posted tasks. | |
| 746 EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u); | |
| 747 test_task_runner_->RunPendingTasks(); | |
| 748 EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4)); | |
| 749 } | |
| 750 | |
| 751 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeup) { | |
| 752 Initialize(2u, SelectorType::Explicit); | |
| 753 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | |
| 754 | |
| 755 std::vector<int> run_order; | |
| 756 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
| 757 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
| 758 | |
| 759 selector_->AppendQueueToService(1); | |
| 760 selector_->AppendQueueToService(0); | |
| 761 selector_->AppendQueueToService(0); | |
| 762 | |
| 763 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 764 test_task_runner_->RunUntilIdle(); | |
| 765 EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM. | |
| 766 | |
| 767 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
| 768 test_task_runner_->RunUntilIdle(); | |
| 769 EXPECT_TRUE(run_order.empty()); // Still shouldn't wake TQM. | |
| 770 | |
| 771 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
| 772 test_task_runner_->RunUntilIdle(); | |
| 773 // Executing a task on an auto pumped queue should wake the TQM. | |
| 774 EXPECT_THAT(run_order, ElementsAre(3, 1, 2)); | |
| 775 } | |
| 776 | |
| 777 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupWhenAlreadyAwake) { | |
| 778 Initialize(2u, SelectorType::Explicit); | |
| 779 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | |
| 780 | |
| 781 std::vector<int> run_order; | |
| 782 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
| 783 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
| 784 | |
| 785 selector_->AppendQueueToService(1); | |
| 786 selector_->AppendQueueToService(0); | |
| 787 | |
| 788 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 789 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
| 790 test_task_runner_->RunUntilIdle(); | |
| 791 EXPECT_THAT(run_order, ElementsAre(2, 1)); // TQM was already awake. | |
| 792 } | |
| 793 | |
| 794 TEST_F(TaskQueueManagerTest, | |
| 795 AutoPumpAfterWakeupTriggeredByManuallyPumpedQueue) { | |
| 796 Initialize(2u, SelectorType::Explicit); | |
| 797 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | |
| 798 manager_->SetPumpPolicy(1, TaskQueueManager::PumpPolicy::MANUAL); | |
| 799 | |
| 800 std::vector<int> run_order; | |
| 801 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
| 802 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
| 803 | |
| 804 selector_->AppendQueueToService(1); | |
| 805 selector_->AppendQueueToService(0); | |
| 806 | |
| 807 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 808 test_task_runner_->RunUntilIdle(); | |
| 809 EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM. | |
| 810 | |
| 811 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
| 812 test_task_runner_->RunUntilIdle(); | |
| 813 // This still shouldn't wake TQM as manual queue was not pumped. | |
| 814 EXPECT_TRUE(run_order.empty()); | |
| 815 | |
| 816 manager_->PumpQueue(1); | |
| 817 test_task_runner_->RunUntilIdle(); | |
| 818 // Executing a task on an auto pumped queue should wake the TQM. | |
| 819 EXPECT_THAT(run_order, ElementsAre(2, 1)); | |
| 820 } | |
| 821 | |
| 822 void TestPostingTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
| 823 base::Closure task) { | |
| 824 task_runner->PostTask(FROM_HERE, task); | |
| 825 } | |
| 826 | |
| 827 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromTask) { | |
| 828 Initialize(2u, SelectorType::Explicit); | |
| 829 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | |
| 830 | |
| 831 std::vector<int> run_order; | |
| 832 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
| 833 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
| 834 | |
| 835 selector_->AppendQueueToService(1); | |
| 836 selector_->AppendQueueToService(1); | |
| 837 selector_->AppendQueueToService(0); | |
| 838 | |
| 839 // Check that a task which posts a task to an auto pump after wakeup queue | |
| 840 // doesn't cause the queue to wake up. | |
| 841 base::Closure after_wakeup_task = base::Bind(&TestTask, 1, &run_order); | |
| 842 runners[1]->PostTask( | |
| 843 FROM_HERE, base::Bind(&TestPostingTask, runners[0], after_wakeup_task)); | |
| 844 test_task_runner_->RunUntilIdle(); | |
| 845 EXPECT_TRUE(run_order.empty()); | |
| 846 | |
| 847 // Wake up the queue. | |
| 848 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
| 849 test_task_runner_->RunUntilIdle(); | |
| 850 EXPECT_THAT(run_order, ElementsAre(2, 1)); | |
| 851 } | |
| 852 | |
| 853 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromMultipleTasks) { | |
| 854 Initialize(2u, SelectorType::Explicit); | |
| 855 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | |
| 856 | |
| 857 std::vector<int> run_order; | |
| 858 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
| 859 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
| 860 | |
| 861 selector_->AppendQueueToService(1); | |
| 862 selector_->AppendQueueToService(1); | |
| 863 selector_->AppendQueueToService(1); | |
| 864 selector_->AppendQueueToService(0); | |
| 865 selector_->AppendQueueToService(0); | |
| 866 | |
| 867 // Check that a task which posts a task to an auto pump after wakeup queue | |
| 868 // doesn't cause the queue to wake up. | |
| 869 base::Closure after_wakeup_task_1 = base::Bind(&TestTask, 1, &run_order); | |
| 870 base::Closure after_wakeup_task_2 = base::Bind(&TestTask, 2, &run_order); | |
| 871 runners[1]->PostTask( | |
| 872 FROM_HERE, base::Bind(&TestPostingTask, runners[0], after_wakeup_task_1)); | |
| 873 runners[1]->PostTask( | |
| 874 FROM_HERE, base::Bind(&TestPostingTask, runners[0], after_wakeup_task_2)); | |
| 875 test_task_runner_->RunUntilIdle(); | |
| 876 EXPECT_TRUE(run_order.empty()); | |
| 877 | |
| 878 // Wake up the queue. | |
| 879 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
| 880 test_task_runner_->RunUntilIdle(); | |
| 881 EXPECT_THAT(run_order, ElementsAre(3, 1, 2)); | |
| 882 } | |
| 883 | |
| 884 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupBecomesQuiescent) { | |
| 885 Initialize(2u, SelectorType::Explicit); | |
| 886 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | |
| 887 | |
| 888 int run_count = 0; | |
| 889 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
| 890 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
| 891 | |
| 892 selector_->AppendQueueToService(1); | |
| 893 selector_->AppendQueueToService(0); | |
| 894 selector_->AppendQueueToService(0); | |
| 895 // Append extra service queue '0' entries to the selector otherwise test will | |
| 896 // finish even if the RePostingTestTask woke each other up. | |
| 897 selector_->AppendQueueToService(0); | |
| 898 selector_->AppendQueueToService(0); | |
| 899 | |
| 900 // Check that if multiple tasks reposts themselves onto a pump-after-wakeup | |
| 901 // queue they don't wake each other and will eventually stop when no other | |
| 902 // tasks execute. | |
| 903 runners[0]->PostTask(FROM_HERE, | |
| 904 base::Bind(&RePostingTestTask, runners[0], &run_count)); | |
| 905 runners[0]->PostTask(FROM_HERE, | |
| 906 base::Bind(&RePostingTestTask, runners[0], &run_count)); | |
| 907 runners[1]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
| 908 test_task_runner_->RunUntilIdle(); | |
| 909 // The reposting tasks posted to the after wakeup queue shouldn't have woken | |
| 910 // each other up. | |
| 911 EXPECT_EQ(2, run_count); | |
| 912 } | |
| 913 | |
| 914 class MockTaskObserver : public base::MessageLoop::TaskObserver { | |
| 915 public: | |
| 916 MOCK_METHOD1(DidProcessTask, void(const base::PendingTask& task)); | |
| 917 MOCK_METHOD1(WillProcessTask, void(const base::PendingTask& task)); | |
| 918 }; | |
| 919 | |
| 920 TEST_F(TaskQueueManagerTest, TaskObserverAdding) { | |
| 921 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
| 922 MockTaskObserver observer; | |
| 923 | |
| 924 manager_->SetWorkBatchSize(2); | |
| 925 manager_->AddTaskObserver(&observer); | |
| 926 | |
| 927 std::vector<int> run_order; | |
| 928 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 929 manager_->TaskRunnerForQueue(0); | |
| 930 | |
| 931 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 932 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
| 933 | |
| 934 // Two pairs of callbacks for the tasks above plus another one for the | |
| 935 // DoWork() posted by the task queue manager. | |
| 936 EXPECT_CALL(observer, WillProcessTask(_)).Times(3); | |
| 937 EXPECT_CALL(observer, DidProcessTask(_)).Times(3); | |
| 938 message_loop_->RunUntilIdle(); | |
| 939 } | |
| 940 | |
| 941 TEST_F(TaskQueueManagerTest, TaskObserverRemoving) { | |
| 942 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
| 943 MockTaskObserver observer; | |
| 944 manager_->SetWorkBatchSize(2); | |
| 945 manager_->AddTaskObserver(&observer); | |
| 946 manager_->RemoveTaskObserver(&observer); | |
| 947 | |
| 948 std::vector<int> run_order; | |
| 949 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 950 manager_->TaskRunnerForQueue(0); | |
| 951 | |
| 952 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
| 953 | |
| 954 EXPECT_CALL(observer, WillProcessTask(_)).Times(0); | |
| 955 EXPECT_CALL(observer, DidProcessTask(_)).Times(0); | |
| 956 | |
| 957 message_loop_->RunUntilIdle(); | |
| 958 } | |
| 959 | |
| 960 void RemoveObserverTask(TaskQueueManager* manager, | |
| 961 base::MessageLoop::TaskObserver* observer) { | |
| 962 manager->RemoveTaskObserver(observer); | |
| 963 } | |
| 964 | |
| 965 TEST_F(TaskQueueManagerTest, TaskObserverRemovingInsideTask) { | |
| 966 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
| 967 MockTaskObserver observer; | |
| 968 manager_->SetWorkBatchSize(3); | |
| 969 manager_->AddTaskObserver(&observer); | |
| 970 | |
| 971 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 972 manager_->TaskRunnerForQueue(0); | |
| 973 runner->PostTask(FROM_HERE, | |
| 974 base::Bind(&RemoveObserverTask, manager_.get(), &observer)); | |
| 975 | |
| 976 EXPECT_CALL(observer, WillProcessTask(_)).Times(1); | |
| 977 EXPECT_CALL(observer, DidProcessTask(_)).Times(0); | |
| 978 message_loop_->RunUntilIdle(); | |
| 979 } | |
| 980 | |
| 981 TEST_F(TaskQueueManagerTest, ThreadCheckAfterTermination) { | |
| 982 Initialize(1u, SelectorType::Automatic); | |
| 983 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 984 manager_->TaskRunnerForQueue(0); | |
| 985 EXPECT_TRUE(runner->RunsTasksOnCurrentThread()); | |
| 986 manager_.reset(); | |
| 987 EXPECT_TRUE(runner->RunsTasksOnCurrentThread()); | |
| 988 } | |
| 989 | |
| 990 TEST_F(TaskQueueManagerTest, NextPendingDelayedTaskRunTime) { | |
| 991 scoped_refptr<cc::TestNowSource> clock(cc::TestNowSource::Create()); | |
| 992 Initialize(2u, SelectorType::Explicit); | |
| 993 manager_->SetTimeSourceForTesting(make_scoped_ptr(new TestTimeSource(clock))); | |
| 994 | |
| 995 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
| 996 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
| 997 | |
| 998 // With no delayed tasks. | |
| 999 EXPECT_TRUE(manager_->NextPendingDelayedTaskRunTime().is_null()); | |
| 1000 | |
| 1001 // With a non-delayed task. | |
| 1002 runners[0]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
| 1003 EXPECT_TRUE(manager_->NextPendingDelayedTaskRunTime().is_null()); | |
| 1004 | |
| 1005 // With a delayed task. | |
| 1006 base::TimeDelta expected_delay = base::TimeDelta::FromMilliseconds(50); | |
| 1007 runners[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay); | |
| 1008 EXPECT_EQ(clock->Now() + expected_delay, | |
| 1009 manager_->NextPendingDelayedTaskRunTime()); | |
| 1010 | |
| 1011 // With another delayed task in the same queue with a longer delay. | |
| 1012 runners[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), | |
| 1013 base::TimeDelta::FromMilliseconds(100)); | |
| 1014 EXPECT_EQ(clock->Now() + expected_delay, | |
| 1015 manager_->NextPendingDelayedTaskRunTime()); | |
| 1016 | |
| 1017 // With another delayed task in the same queue with a shorter delay. | |
| 1018 expected_delay = base::TimeDelta::FromMilliseconds(20); | |
| 1019 runners[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay); | |
| 1020 EXPECT_EQ(clock->Now() + expected_delay, | |
| 1021 manager_->NextPendingDelayedTaskRunTime()); | |
| 1022 | |
| 1023 // With another delayed task in a different queue with a shorter delay. | |
| 1024 expected_delay = base::TimeDelta::FromMilliseconds(10); | |
| 1025 runners[1]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay); | |
| 1026 EXPECT_EQ(clock->Now() + expected_delay, | |
| 1027 manager_->NextPendingDelayedTaskRunTime()); | |
| 1028 | |
| 1029 // Test it updates as time progresses | |
| 1030 clock->AdvanceNow(expected_delay); | |
| 1031 EXPECT_EQ(clock->Now(), manager_->NextPendingDelayedTaskRunTime()); | |
| 1032 } | |
| 1033 | |
| 1034 TEST_F(TaskQueueManagerTest, NextPendingDelayedTaskRunTime_MultipleQueues) { | |
| 1035 Initialize(3u, SelectorType::Automatic); | |
| 1036 | |
| 1037 scoped_refptr<base::SingleThreadTaskRunner> runners[3] = { | |
| 1038 manager_->TaskRunnerForQueue(0), | |
| 1039 manager_->TaskRunnerForQueue(1), | |
| 1040 manager_->TaskRunnerForQueue(2)}; | |
| 1041 | |
| 1042 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(50); | |
| 1043 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(5); | |
| 1044 base::TimeDelta delay3 = base::TimeDelta::FromMilliseconds(10); | |
| 1045 runners[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay1); | |
| 1046 runners[1]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay2); | |
| 1047 runners[2]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay3); | |
| 1048 | |
| 1049 EXPECT_EQ(now_src_->Now() + delay2, | |
| 1050 manager_->NextPendingDelayedTaskRunTime()); | |
| 1051 } | |
| 1052 | |
| 1053 TEST_F(TaskQueueManagerTest, DeleteTaskQueueManagerInsideATask) { | |
| 1054 Initialize(1u, SelectorType::Automatic); | |
| 1055 | |
| 1056 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
| 1057 manager_->TaskRunnerForQueue(0); | |
| 1058 runner->PostTask(FROM_HERE, | |
| 1059 base::Bind(&TaskQueueManagerTest::DeleteTaskQueueManager, | |
| 1060 base::Unretained(this))); | |
| 1061 | |
| 1062 // This should not crash, assuming DoWork detects the TaskQueueManager has | |
| 1063 // been deleted. | |
| 1064 test_task_runner_->RunUntilIdle(); | |
| 1065 } | |
| 1066 | |
| 1067 TEST_F(TaskQueueManagerTest, GetAndClearTaskWasRunBitmap) { | |
| 1068 Initialize(3u, SelectorType::Automatic); | |
| 1069 | |
| 1070 scoped_refptr<base::SingleThreadTaskRunner> runners[3] = { | |
| 1071 manager_->TaskRunnerForQueue(0), | |
| 1072 manager_->TaskRunnerForQueue(1), | |
| 1073 manager_->TaskRunnerForQueue(2)}; | |
| 1074 | |
| 1075 EXPECT_EQ(0ul, manager_->GetAndClearTaskWasRunOnQueueBitmap()); | |
| 1076 | |
| 1077 runners[0]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
| 1078 test_task_runner_->RunUntilIdle(); | |
| 1079 EXPECT_EQ(1ul << 0, manager_->GetAndClearTaskWasRunOnQueueBitmap()); | |
| 1080 | |
| 1081 runners[1]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
| 1082 test_task_runner_->RunUntilIdle(); | |
| 1083 EXPECT_EQ(1ul << 1, manager_->GetAndClearTaskWasRunOnQueueBitmap()); | |
| 1084 | |
| 1085 runners[2]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
| 1086 test_task_runner_->RunUntilIdle(); | |
| 1087 EXPECT_EQ(1ul << 2, manager_->GetAndClearTaskWasRunOnQueueBitmap()); | |
| 1088 | |
| 1089 runners[0]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
| 1090 runners[2]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
| 1091 test_task_runner_->RunUntilIdle(); | |
| 1092 EXPECT_EQ(1ul << 0 | 1ul << 2, | |
| 1093 manager_->GetAndClearTaskWasRunOnQueueBitmap()); | |
| 1094 EXPECT_EQ(0ul, manager_->GetAndClearTaskWasRunOnQueueBitmap()); | |
| 1095 } | |
| 1096 | |
| 1097 TEST_F(TaskQueueManagerTest, GetAndClearTaskWasRunBitmap_ManyQueues) { | |
| 1098 Initialize(64u, SelectorType::Automatic); | |
| 1099 | |
| 1100 manager_->TaskRunnerForQueue(63)->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
| 1101 test_task_runner_->RunUntilIdle(); | |
| 1102 EXPECT_EQ(1ull << 63, manager_->GetAndClearTaskWasRunOnQueueBitmap()); | |
| 1103 } | |
| 1104 | |
| 1105 } // namespace | |
| 1106 } // namespace content | |
| OLD | NEW |