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.
5 #include "content/renderer/scheduler/task_queue_manager.h"
7 #include "base/test/test_simple_task_runner.h"
8 #include "base/threading/thread.h"
9 #include "cc/test/test_now_source.h"
10 #include "content/renderer/scheduler/task_queue_selector.h"
11 #include "testing/gmock/include/gmock/gmock.h"
13 using testing::ElementsAre
;
19 class SelectorForTest
: public TaskQueueSelector
{
23 void RegisterWorkQueues(
24 const std::vector
<const base::TaskQueue
*>& work_queues
) override
{
25 work_queues_
= work_queues
;
28 bool SelectWorkQueueToService(size_t* out_queue_index
) override
{
29 if (queues_to_service_
.empty())
31 *out_queue_index
= queues_to_service_
.front();
32 queues_to_service_
.pop_front();
36 void AppendQueueToService(size_t queue_index
) {
37 queues_to_service_
.push_back(queue_index
);
40 const std::vector
<const base::TaskQueue
*>& work_queues() {
44 void AsValueInto(base::trace_event::TracedValue
* state
) const override
{
48 std::deque
<size_t> queues_to_service_
;
49 std::vector
<const base::TaskQueue
*> work_queues_
;
51 DISALLOW_COPY_AND_ASSIGN(SelectorForTest
);
54 class TaskQueueManagerTest
: public testing::Test
{
56 void Initialize(size_t num_queues
) {
57 test_task_runner_
= make_scoped_refptr(new base::TestSimpleTaskRunner());
58 selector_
= make_scoped_ptr(new SelectorForTest
);
59 manager_
= make_scoped_ptr(
60 new TaskQueueManager(num_queues
, test_task_runner_
, selector_
.get()));
61 EXPECT_EQ(num_queues
, selector_
->work_queues().size());
64 void InitializeWithRealMessageLoop(size_t num_queues
) {
65 message_loop_
.reset(new base::MessageLoop());
66 selector_
= make_scoped_ptr(new SelectorForTest
);
67 manager_
= make_scoped_ptr(new TaskQueueManager(
68 num_queues
, message_loop_
->task_runner(), selector_
.get()));
69 EXPECT_EQ(num_queues
, selector_
->work_queues().size());
72 scoped_refptr
<base::TestSimpleTaskRunner
> test_task_runner_
;
73 scoped_ptr
<SelectorForTest
> selector_
;
74 scoped_ptr
<TaskQueueManager
> manager_
;
75 scoped_ptr
<base::MessageLoop
> message_loop_
;
78 void PostFromNestedRunloop(base::MessageLoop
* message_loop
,
79 base::SingleThreadTaskRunner
* runner
,
80 std::vector
<std::pair
<base::Closure
, bool>>* tasks
) {
81 base::MessageLoop::ScopedNestableTaskAllower
allow(message_loop
);
82 for (std::pair
<base::Closure
, bool>& pair
: *tasks
) {
84 runner
->PostTask(FROM_HERE
, pair
.first
);
86 runner
->PostNonNestableTask(FROM_HERE
, pair
.first
);
89 message_loop
->RunUntilIdle();
92 void TestTask(int value
, std::vector
<int>* out_result
) {
93 out_result
->push_back(value
);
96 TEST_F(TaskQueueManagerTest
, SingleQueuePosting
) {
99 std::vector
<int> run_order
;
100 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
101 manager_
->TaskRunnerForQueue(0);
103 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
104 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
105 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
));
107 selector_
->AppendQueueToService(0);
108 selector_
->AppendQueueToService(0);
109 selector_
->AppendQueueToService(0);
111 test_task_runner_
->RunUntilIdle();
112 EXPECT_THAT(run_order
, ElementsAre(1, 2, 3));
115 TEST_F(TaskQueueManagerTest
, MultiQueuePosting
) {
118 std::vector
<int> run_order
;
119 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[3] = {
120 manager_
->TaskRunnerForQueue(0),
121 manager_
->TaskRunnerForQueue(1),
122 manager_
->TaskRunnerForQueue(2)};
124 selector_
->AppendQueueToService(0);
125 selector_
->AppendQueueToService(1);
126 selector_
->AppendQueueToService(2);
127 selector_
->AppendQueueToService(0);
128 selector_
->AppendQueueToService(1);
129 selector_
->AppendQueueToService(2);
131 runners
[0]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
132 runners
[0]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
133 runners
[1]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
));
134 runners
[1]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 4, &run_order
));
135 runners
[2]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 5, &run_order
));
136 runners
[2]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 6, &run_order
));
138 test_task_runner_
->RunUntilIdle();
139 EXPECT_THAT(run_order
, ElementsAre(1, 3, 5, 2, 4, 6));
142 TEST_F(TaskQueueManagerTest
, NonNestableTaskPosting
) {
143 InitializeWithRealMessageLoop(1u);
145 std::vector
<int> run_order
;
146 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
147 manager_
->TaskRunnerForQueue(0);
149 selector_
->AppendQueueToService(0);
151 runner
->PostNonNestableTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
153 message_loop_
->RunUntilIdle();
154 EXPECT_THAT(run_order
, ElementsAre(1));
157 TEST_F(TaskQueueManagerTest
, NonNestableTaskExecutesInExpectedOrder
) {
158 InitializeWithRealMessageLoop(1u);
160 std::vector
<int> run_order
;
161 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
162 manager_
->TaskRunnerForQueue(0);
164 selector_
->AppendQueueToService(0);
165 selector_
->AppendQueueToService(0);
166 selector_
->AppendQueueToService(0);
167 selector_
->AppendQueueToService(0);
168 selector_
->AppendQueueToService(0);
170 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
171 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
172 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
));
173 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 4, &run_order
));
174 runner
->PostNonNestableTask(FROM_HERE
, base::Bind(&TestTask
, 5, &run_order
));
176 message_loop_
->RunUntilIdle();
177 EXPECT_THAT(run_order
, ElementsAre(1, 2, 3, 4, 5));
180 TEST_F(TaskQueueManagerTest
, NonNestableTaskDoesntExecuteInNestedLoop
) {
181 InitializeWithRealMessageLoop(1u);
183 std::vector
<int> run_order
;
184 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
185 manager_
->TaskRunnerForQueue(0);
187 selector_
->AppendQueueToService(0);
188 selector_
->AppendQueueToService(0);
189 selector_
->AppendQueueToService(0);
190 selector_
->AppendQueueToService(0);
191 selector_
->AppendQueueToService(0);
192 selector_
->AppendQueueToService(0);
194 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
195 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
197 std::vector
<std::pair
<base::Closure
, bool>> tasks_to_post_from_nested_loop
;
198 tasks_to_post_from_nested_loop
.push_back(
199 std::make_pair(base::Bind(&TestTask
, 3, &run_order
), false));
200 tasks_to_post_from_nested_loop
.push_back(
201 std::make_pair(base::Bind(&TestTask
, 4, &run_order
), true));
202 tasks_to_post_from_nested_loop
.push_back(
203 std::make_pair(base::Bind(&TestTask
, 5, &run_order
), true));
207 base::Bind(&PostFromNestedRunloop
, message_loop_
.get(), runner
,
208 base::Unretained(&tasks_to_post_from_nested_loop
)));
210 message_loop_
->RunUntilIdle();
211 // Note we expect task 3 to run last because it's non-nestable.
212 EXPECT_THAT(run_order
, ElementsAre(1, 2, 4, 5, 3));
215 TEST_F(TaskQueueManagerTest
, QueuePolling
) {
218 std::vector
<int> run_order
;
219 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
220 manager_
->TaskRunnerForQueue(0);
222 EXPECT_TRUE(manager_
->IsQueueEmpty(0));
223 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
224 EXPECT_FALSE(manager_
->IsQueueEmpty(0));
226 selector_
->AppendQueueToService(0);
227 test_task_runner_
->RunUntilIdle();
228 EXPECT_TRUE(manager_
->IsQueueEmpty(0));
231 TEST_F(TaskQueueManagerTest
, DelayedTaskPosting
) {
234 std::vector
<int> run_order
;
235 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
236 manager_
->TaskRunnerForQueue(0);
238 selector_
->AppendQueueToService(0);
240 base::TimeDelta
delay(base::TimeDelta::FromMilliseconds(10));
241 runner
->PostDelayedTask(
242 FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
), delay
);
243 EXPECT_EQ(delay
, test_task_runner_
->NextPendingTaskDelay());
244 EXPECT_TRUE(manager_
->IsQueueEmpty(0));
245 EXPECT_TRUE(run_order
.empty());
247 // The task is inserted to the incoming queue only after the delay.
248 test_task_runner_
->RunPendingTasks();
249 EXPECT_FALSE(manager_
->IsQueueEmpty(0));
250 EXPECT_TRUE(run_order
.empty());
252 // After the delay the task runs normally.
253 selector_
->AppendQueueToService(0);
254 test_task_runner_
->RunUntilIdle();
255 EXPECT_THAT(run_order
, ElementsAre(1));
258 TEST_F(TaskQueueManagerTest
, DelayedTaskDoesNotStayDelayed
) {
261 std::vector
<int> run_order
;
262 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
263 manager_
->TaskRunnerForQueue(0);
265 selector_
->AppendQueueToService(0);
267 base::TimeDelta
delay(base::TimeDelta::FromMilliseconds(10));
268 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
),
270 test_task_runner_
->RunPendingTasks();
272 // Reload the work queue so we see the next pending task. It should no longer
273 // be marked as delayed.
274 manager_
->PumpQueue(0);
275 EXPECT_TRUE(selector_
->work_queues()[0]->front().delayed_run_time
.is_null());
277 // Let the task run normally.
278 selector_
->AppendQueueToService(0);
279 test_task_runner_
->RunUntilIdle();
280 EXPECT_THAT(run_order
, ElementsAre(1));
283 TEST_F(TaskQueueManagerTest
, ManualPumping
) {
285 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL
);
287 std::vector
<int> run_order
;
288 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
289 manager_
->TaskRunnerForQueue(0);
291 // Posting a task when pumping is disabled doesn't result in work getting
293 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
294 EXPECT_FALSE(test_task_runner_
->HasPendingTask());
296 // However polling still works.
297 EXPECT_FALSE(manager_
->IsQueueEmpty(0));
299 // After pumping the task runs normally.
300 manager_
->PumpQueue(0);
301 EXPECT_TRUE(test_task_runner_
->HasPendingTask());
302 selector_
->AppendQueueToService(0);
303 test_task_runner_
->RunUntilIdle();
304 EXPECT_THAT(run_order
, ElementsAre(1));
307 TEST_F(TaskQueueManagerTest
, ManualPumpingToggle
) {
309 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL
);
311 std::vector
<int> run_order
;
312 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
313 manager_
->TaskRunnerForQueue(0);
315 // Posting a task when pumping is disabled doesn't result in work getting
317 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
318 EXPECT_FALSE(test_task_runner_
->HasPendingTask());
320 // When pumping is enabled the task runs normally.
321 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AUTO
);
322 EXPECT_TRUE(test_task_runner_
->HasPendingTask());
323 selector_
->AppendQueueToService(0);
324 test_task_runner_
->RunUntilIdle();
325 EXPECT_THAT(run_order
, ElementsAre(1));
328 TEST_F(TaskQueueManagerTest
, DenyRunning
) {
331 std::vector
<int> run_order
;
332 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
333 manager_
->TaskRunnerForQueue(0);
334 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
336 // Since we haven't appended a work queue to be selected, the task doesn't
338 test_task_runner_
->RunUntilIdle();
339 EXPECT_TRUE(run_order
.empty());
341 // Pumping the queue again with a selected work queue runs the task.
342 manager_
->PumpQueue(0);
343 selector_
->AppendQueueToService(0);
344 test_task_runner_
->RunUntilIdle();
345 EXPECT_THAT(run_order
, ElementsAre(1));
348 TEST_F(TaskQueueManagerTest
, ManualPumpingWithDelayedTask
) {
350 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL
);
352 std::vector
<int> run_order
;
353 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
354 manager_
->TaskRunnerForQueue(0);
356 // Posting a delayed task when pumping will apply the delay, but won't cause
357 // work to executed afterwards.
358 base::TimeDelta
delay(base::TimeDelta::FromMilliseconds(10));
359 runner
->PostDelayedTask(
360 FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
), delay
);
361 test_task_runner_
->RunUntilIdle();
362 EXPECT_TRUE(run_order
.empty());
364 // After pumping the task runs normally.
365 manager_
->PumpQueue(0);
366 EXPECT_TRUE(test_task_runner_
->HasPendingTask());
367 selector_
->AppendQueueToService(0);
368 test_task_runner_
->RunUntilIdle();
369 EXPECT_THAT(run_order
, ElementsAre(1));
372 TEST_F(TaskQueueManagerTest
, ManualPumpingWithNonEmptyWorkQueue
) {
374 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL
);
376 std::vector
<int> run_order
;
377 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
378 manager_
->TaskRunnerForQueue(0);
380 // Posting two tasks and pumping twice should result in two tasks in the work
382 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
383 manager_
->PumpQueue(0);
384 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
385 manager_
->PumpQueue(0);
387 EXPECT_EQ(2u, selector_
->work_queues()[0]->size());
390 void ReentrantTestTask(scoped_refptr
<base::SingleThreadTaskRunner
> runner
,
392 std::vector
<int>* out_result
) {
393 out_result
->push_back(countdown
);
395 runner
->PostTask(FROM_HERE
,
396 Bind(&ReentrantTestTask
, runner
, countdown
, out_result
));
400 TEST_F(TaskQueueManagerTest
, ReentrantPosting
) {
403 std::vector
<int> run_order
;
404 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
405 manager_
->TaskRunnerForQueue(0);
407 runner
->PostTask(FROM_HERE
, Bind(&ReentrantTestTask
, runner
, 3, &run_order
));
409 selector_
->AppendQueueToService(0);
410 selector_
->AppendQueueToService(0);
411 selector_
->AppendQueueToService(0);
413 test_task_runner_
->RunUntilIdle();
414 EXPECT_THAT(run_order
, ElementsAre(3, 2, 1));
417 TEST_F(TaskQueueManagerTest
, NoTasksAfterShutdown
) {
420 std::vector
<int> run_order
;
421 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
422 manager_
->TaskRunnerForQueue(0);
424 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
427 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
429 test_task_runner_
->RunUntilIdle();
430 EXPECT_TRUE(run_order
.empty());
433 void PostTaskToRunner(scoped_refptr
<base::SingleThreadTaskRunner
> runner
,
434 std::vector
<int>* run_order
) {
435 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, run_order
));
438 TEST_F(TaskQueueManagerTest
, PostFromThread
) {
439 InitializeWithRealMessageLoop(1u);
441 std::vector
<int> run_order
;
442 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
443 manager_
->TaskRunnerForQueue(0);
445 base::Thread
thread("TestThread");
447 thread
.message_loop()->PostTask(
448 FROM_HERE
, base::Bind(&PostTaskToRunner
, runner
, &run_order
));
451 selector_
->AppendQueueToService(0);
452 message_loop_
->RunUntilIdle();
453 EXPECT_THAT(run_order
, ElementsAre(1));
456 void RePostingTestTask(scoped_refptr
<base::SingleThreadTaskRunner
> runner
,
461 Bind(&RePostingTestTask
, base::Unretained(runner
.get()), run_count
));
464 TEST_F(TaskQueueManagerTest
, DoWorkCantPostItselfMultipleTimes
) {
466 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
467 manager_
->TaskRunnerForQueue(0);
470 runner
->PostTask(FROM_HERE
,
471 base::Bind(&RePostingTestTask
, runner
, &run_count
));
473 selector_
->AppendQueueToService(0);
474 selector_
->AppendQueueToService(0);
475 selector_
->AppendQueueToService(0);
477 test_task_runner_
->RunPendingTasks();
478 // NOTE without the executing_task_ check in MaybePostDoWorkOnMainRunner there
479 // will be two tasks here.
480 EXPECT_EQ(1u, test_task_runner_
->GetPendingTasks().size());
481 EXPECT_EQ(1, run_count
);
484 TEST_F(TaskQueueManagerTest
, PostFromNestedRunloop
) {
485 InitializeWithRealMessageLoop(1u);
487 selector_
->AppendQueueToService(0);
488 selector_
->AppendQueueToService(0);
489 selector_
->AppendQueueToService(0);
490 selector_
->AppendQueueToService(0);
492 std::vector
<int> run_order
;
493 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
494 manager_
->TaskRunnerForQueue(0);
496 std::vector
<std::pair
<base::Closure
, bool>> tasks_to_post_from_nested_loop
;
497 tasks_to_post_from_nested_loop
.push_back(
498 std::make_pair(base::Bind(&TestTask
, 1, &run_order
), true));
500 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 0, &run_order
));
502 FROM_HERE
, base::Bind(&PostFromNestedRunloop
, message_loop_
.get(), runner
,
503 base::Unretained(&tasks_to_post_from_nested_loop
)));
504 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
506 message_loop_
->RunUntilIdle();
508 EXPECT_THAT(run_order
, ElementsAre(0, 2, 1));
511 TEST_F(TaskQueueManagerTest
, WorkBatching
) {
514 manager_
->SetWorkBatchSize(2);
516 std::vector
<int> run_order
;
517 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
518 manager_
->TaskRunnerForQueue(0);
520 selector_
->AppendQueueToService(0);
521 selector_
->AppendQueueToService(0);
522 selector_
->AppendQueueToService(0);
523 selector_
->AppendQueueToService(0);
525 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
526 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
527 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
));
528 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 4, &run_order
));
530 // Running one task in the host message loop should cause two posted tasks to
532 EXPECT_EQ(test_task_runner_
->GetPendingTasks().size(), 1u);
533 test_task_runner_
->RunPendingTasks();
534 EXPECT_THAT(run_order
, ElementsAre(1, 2));
536 // The second task runs the remaining two posted tasks.
537 EXPECT_EQ(test_task_runner_
->GetPendingTasks().size(), 1u);
538 test_task_runner_
->RunPendingTasks();
539 EXPECT_THAT(run_order
, ElementsAre(1, 2, 3, 4));
542 void AdvanceNowTestTask(int value
,
543 std::vector
<int>* out_result
,
544 scoped_refptr
<cc::TestNowSource
> time_source
,
545 base::TimeDelta delta
) {
546 TestTask(value
, out_result
);
547 time_source
->AdvanceNow(delta
);
550 TEST_F(TaskQueueManagerTest
, InterruptWorkBatchForDelayedTask
) {
551 scoped_refptr
<cc::TestNowSource
> clock(cc::TestNowSource::Create());
554 manager_
->SetWorkBatchSize(2);
555 manager_
->SetTimeSourceForTesting(clock
);
557 std::vector
<int> run_order
;
558 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
559 manager_
->TaskRunnerForQueue(0);
561 selector_
->AppendQueueToService(0);
562 selector_
->AppendQueueToService(0);
563 selector_
->AppendQueueToService(0);
565 base::TimeDelta
delta(base::TimeDelta::FromMilliseconds(10));
567 FROM_HERE
, base::Bind(&AdvanceNowTestTask
, 2, &run_order
, clock
, delta
));
569 FROM_HERE
, base::Bind(&AdvanceNowTestTask
, 3, &run_order
, clock
, delta
));
571 base::TimeDelta
delay(base::TimeDelta::FromMilliseconds(5));
572 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
),
575 // At this point we have two posted tasks: one for DoWork and one of the
576 // delayed task. Only the first non-delayed task should get executed because
577 // the work batch is interrupted by the pending delayed task.
578 EXPECT_EQ(test_task_runner_
->GetPendingTasks().size(), 2u);
579 test_task_runner_
->RunPendingTasks();
580 EXPECT_THAT(run_order
, ElementsAre(2));
582 // Running all remaining tasks should execute both pending tasks.
583 test_task_runner_
->RunUntilIdle();
584 EXPECT_THAT(run_order
, ElementsAre(2, 3, 1));
587 TEST_F(TaskQueueManagerTest
, AutoPumpAfterWakeup
) {
589 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP
);
591 std::vector
<int> run_order
;
592 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[2] = {
593 manager_
->TaskRunnerForQueue(0), manager_
->TaskRunnerForQueue(1)};
595 selector_
->AppendQueueToService(1);
596 selector_
->AppendQueueToService(0);
597 selector_
->AppendQueueToService(0);
599 runners
[0]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
600 test_task_runner_
->RunUntilIdle();
601 EXPECT_TRUE(run_order
.empty()); // Shouldn't run - no other task to wake TQM.
603 runners
[0]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
604 test_task_runner_
->RunUntilIdle();
605 EXPECT_TRUE(run_order
.empty()); // Still shouldn't wake TQM.
607 runners
[1]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
));
608 test_task_runner_
->RunUntilIdle();
609 // Executing a task on an auto pumped queue should wake the TQM.
610 EXPECT_THAT(run_order
, ElementsAre(3, 1, 2));
613 TEST_F(TaskQueueManagerTest
, AutoPumpAfterWakeupWhenAlreadyAwake
) {
615 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP
);
617 std::vector
<int> run_order
;
618 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[2] = {
619 manager_
->TaskRunnerForQueue(0), manager_
->TaskRunnerForQueue(1)};
621 selector_
->AppendQueueToService(1);
622 selector_
->AppendQueueToService(0);
624 runners
[0]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
625 runners
[1]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
626 test_task_runner_
->RunUntilIdle();
627 EXPECT_THAT(run_order
, ElementsAre(2, 1)); // TQM was already awake.
630 TEST_F(TaskQueueManagerTest
,
631 AutoPumpAfterWakeupTriggeredByManuallyPumpedQueue
) {
633 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP
);
634 manager_
->SetPumpPolicy(1, TaskQueueManager::PumpPolicy::MANUAL
);
636 std::vector
<int> run_order
;
637 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[2] = {
638 manager_
->TaskRunnerForQueue(0), manager_
->TaskRunnerForQueue(1)};
640 selector_
->AppendQueueToService(1);
641 selector_
->AppendQueueToService(0);
643 runners
[0]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
644 test_task_runner_
->RunUntilIdle();
645 EXPECT_TRUE(run_order
.empty()); // Shouldn't run - no other task to wake TQM.
647 runners
[1]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
648 test_task_runner_
->RunUntilIdle();
649 // This still shouldn't wake TQM as manual queue was not pumped.
650 EXPECT_TRUE(run_order
.empty());
652 manager_
->PumpQueue(1);
653 test_task_runner_
->RunUntilIdle();
654 // Executing a task on an auto pumped queue should wake the TQM.
655 EXPECT_THAT(run_order
, ElementsAre(2, 1));
658 void TestPostingTask(scoped_refptr
<base::SingleThreadTaskRunner
> task_runner
,
659 base::Closure task
) {
660 task_runner
->PostTask(FROM_HERE
, task
);
663 TEST_F(TaskQueueManagerTest
, AutoPumpAfterWakeupFromTask
) {
665 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP
);
667 std::vector
<int> run_order
;
668 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[2] = {
669 manager_
->TaskRunnerForQueue(0), manager_
->TaskRunnerForQueue(1)};
671 selector_
->AppendQueueToService(1);
672 selector_
->AppendQueueToService(1);
673 selector_
->AppendQueueToService(0);
675 // Check that a task which posts a task to an auto pump after wakeup queue
676 // doesn't cause the queue to wake up.
677 base::Closure after_wakeup_task
= base::Bind(&TestTask
, 1, &run_order
);
678 runners
[1]->PostTask(
680 base::Bind(&TestPostingTask
, runners
[0], after_wakeup_task
));
681 test_task_runner_
->RunUntilIdle();
682 EXPECT_TRUE(run_order
.empty());
684 // Wake up the queue.
685 runners
[1]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
686 test_task_runner_
->RunUntilIdle();
687 EXPECT_THAT(run_order
, ElementsAre(2, 1));
690 TEST_F(TaskQueueManagerTest
, AutoPumpAfterWakeupFromMultipleTasks
) {
692 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP
);
694 std::vector
<int> run_order
;
695 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[2] = {
696 manager_
->TaskRunnerForQueue(0), manager_
->TaskRunnerForQueue(1)};
698 selector_
->AppendQueueToService(1);
699 selector_
->AppendQueueToService(1);
700 selector_
->AppendQueueToService(1);
701 selector_
->AppendQueueToService(0);
702 selector_
->AppendQueueToService(0);
704 // Check that a task which posts a task to an auto pump after wakeup queue
705 // doesn't cause the queue to wake up.
706 base::Closure after_wakeup_task_1
= base::Bind(&TestTask
, 1, &run_order
);
707 base::Closure after_wakeup_task_2
= base::Bind(&TestTask
, 2, &run_order
);
708 runners
[1]->PostTask(
710 base::Bind(&TestPostingTask
, runners
[0], after_wakeup_task_1
));
711 runners
[1]->PostTask(
713 base::Bind(&TestPostingTask
, runners
[0], after_wakeup_task_2
));
714 test_task_runner_
->RunUntilIdle();
715 EXPECT_TRUE(run_order
.empty());
717 // Wake up the queue.
718 runners
[1]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
));
719 test_task_runner_
->RunUntilIdle();
720 EXPECT_THAT(run_order
, ElementsAre(3, 1, 2));
723 void NullTestTask() {
726 TEST_F(TaskQueueManagerTest
, AutoPumpAfterWakeupBecomesQuiescent
) {
728 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP
);
731 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[2] = {
732 manager_
->TaskRunnerForQueue(0), manager_
->TaskRunnerForQueue(1)};
734 selector_
->AppendQueueToService(1);
735 selector_
->AppendQueueToService(0);
736 selector_
->AppendQueueToService(0);
737 // Append extra service queue '0' entries to the selector otherwise test will
738 // finish even if the RePostingTestTask woke each other up.
739 selector_
->AppendQueueToService(0);
740 selector_
->AppendQueueToService(0);
742 // Check that if multiple tasks reposts themselves onto a pump-after-wakeup
743 // queue they don't wake each other and will eventually stop when no other
745 runners
[0]->PostTask(FROM_HERE
,
746 base::Bind(&RePostingTestTask
, runners
[0], &run_count
));
747 runners
[0]->PostTask(FROM_HERE
,
748 base::Bind(&RePostingTestTask
, runners
[0], &run_count
));
749 runners
[1]->PostTask(FROM_HERE
, base::Bind(&NullTestTask
));
750 test_task_runner_
->RunUntilIdle();
751 // The reposting tasks posted to the after wakeup queue shouldn't have woken
753 EXPECT_EQ(2, run_count
);
756 class MockTaskObserver
: public base::MessageLoop::TaskObserver
{
758 MOCK_METHOD1(DidProcessTask
, void(const base::PendingTask
& task
));
759 MOCK_METHOD1(WillProcessTask
, void(const base::PendingTask
& task
));
762 TEST_F(TaskQueueManagerTest
, TaskObserverAdding
) {
763 InitializeWithRealMessageLoop(1u);
764 MockTaskObserver observer
;
766 manager_
->SetWorkBatchSize(2);
767 manager_
->AddTaskObserver(&observer
);
769 std::vector
<int> run_order
;
770 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
771 manager_
->TaskRunnerForQueue(0);
773 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
774 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
776 selector_
->AppendQueueToService(0);
777 selector_
->AppendQueueToService(0);
779 // Two pairs of callbacks for the tasks above plus another one for the
780 // DoWork() posted by the task queue manager.
781 EXPECT_CALL(observer
, WillProcessTask(_
)).Times(3);
782 EXPECT_CALL(observer
, DidProcessTask(_
)).Times(3);
783 message_loop_
->RunUntilIdle();
786 TEST_F(TaskQueueManagerTest
, TaskObserverRemoving
) {
787 InitializeWithRealMessageLoop(1u);
788 MockTaskObserver observer
;
789 manager_
->SetWorkBatchSize(2);
790 manager_
->AddTaskObserver(&observer
);
791 manager_
->RemoveTaskObserver(&observer
);
793 std::vector
<int> run_order
;
794 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
795 manager_
->TaskRunnerForQueue(0);
797 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
799 EXPECT_CALL(observer
, WillProcessTask(_
)).Times(0);
800 EXPECT_CALL(observer
, DidProcessTask(_
)).Times(0);
802 selector_
->AppendQueueToService(0);
803 message_loop_
->RunUntilIdle();
806 void RemoveObserverTask(TaskQueueManager
* manager
,
807 base::MessageLoop::TaskObserver
* observer
) {
808 manager
->RemoveTaskObserver(observer
);
811 TEST_F(TaskQueueManagerTest
, TaskObserverRemovingInsideTask
) {
812 InitializeWithRealMessageLoop(1u);
813 MockTaskObserver observer
;
814 manager_
->SetWorkBatchSize(3);
815 manager_
->AddTaskObserver(&observer
);
817 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
818 manager_
->TaskRunnerForQueue(0);
819 runner
->PostTask(FROM_HERE
,
820 base::Bind(&RemoveObserverTask
, manager_
.get(), &observer
));
822 selector_
->AppendQueueToService(0);
824 EXPECT_CALL(observer
, WillProcessTask(_
)).Times(1);
825 EXPECT_CALL(observer
, DidProcessTask(_
)).Times(0);
826 message_loop_
->RunUntilIdle();
830 } // namespace content