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

Side by Side Diff: content/renderer/scheduler/task_queue_manager_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698