1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// found in the LICENSE file.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "cc/test/ordered_simple_task_runner.h"
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <limits>
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <set>
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <sstream>
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <string>
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <vector>
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/auto_reset.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/debug/trace_event.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/debug/trace_event_argument.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/string_number_conversions.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define TRACE_TASK(function, task) \
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_INSTANT1(            \
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "cc", function, TRACE_EVENT_SCOPE_THREAD, "task", task.AsValue());
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define TRACE_TASK_RUN(function, tag, task)
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace cc {
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// TestOrderablePendingTask implementation
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTestOrderablePendingTask::TestOrderablePendingTask()
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : base::TestPendingTask(),
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      task_id_(TestOrderablePendingTask::task_id_counter++) {
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTestOrderablePendingTask::TestOrderablePendingTask(
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const tracked_objects::Location& location,
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::Closure& task,
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::TimeTicks post_time,
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::TimeDelta delay,
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TestNestability nestability)
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : base::TestPendingTask(location, task, post_time, delay, nestability),
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      task_id_(TestOrderablePendingTask::task_id_counter++) {
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccisize_t TestOrderablePendingTask::task_id_counter = 0;
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTestOrderablePendingTask::~TestOrderablePendingTask() {
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool TestOrderablePendingTask::operator==(
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const TestOrderablePendingTask& other) const {
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return task_id_ == other.task_id_;
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool TestOrderablePendingTask::operator<(
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const TestOrderablePendingTask& other) const {
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (*this == other)
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (GetTimeToRun() == other.GetTimeToRun()) {
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return task_id_ < other.task_id_;
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return ShouldRunBefore(other);
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_refptr<base::debug::ConvertableToTraceFormat>
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTestOrderablePendingTask::AsValue() const {
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<base::debug::TracedValue> state =
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new base::debug::TracedValue();
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AsValueInto(state.get());
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return state;
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid TestOrderablePendingTask::AsValueInto(
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::debug::TracedValue* state) const {
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  state->SetInteger("id", task_id_);
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  state->SetInteger("run_at", GetTimeToRun().ToInternalValue());
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  state->SetString("posted_from", location.ToString());
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciOrderedSimpleTaskRunner::OrderedSimpleTaskRunner()
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : advance_now_(true),
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      now_src_(TestNowSource::Create(0)),
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      inside_run_tasks_until_(false) {
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciOrderedSimpleTaskRunner::OrderedSimpleTaskRunner(
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_refptr<TestNowSource> now_src,
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool advance_now)
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : advance_now_(advance_now),
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      now_src_(now_src),
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      max_tasks_(kAbsoluteMaxTasks),
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      inside_run_tasks_until_(false) {
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)OrderedSimpleTaskRunner::~OrderedSimpleTaskRunner() {}
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// base::TestSimpleTaskRunner implementation
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool OrderedSimpleTaskRunner::PostDelayedTask(
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const tracked_objects::Location& from_here,
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::Closure& task,
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::TimeDelta delay) {
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestOrderablePendingTask pt(
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      from_here, task, now_src_->Now(), delay, base::TestPendingTask::NESTABLE);
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_TASK("OrderedSimpleTaskRunner::PostDelayedTask", pt);
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pending_tasks_.insert(pt);
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool OrderedSimpleTaskRunner::PostNonNestableDelayedTask(
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const tracked_objects::Location& from_here,
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::Closure& task,
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::TimeDelta delay) {
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestOrderablePendingTask pt(from_here,
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              task,
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              now_src_->Now(),
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              delay,
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              base::TestPendingTask::NON_NESTABLE);
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_TASK("OrderedSimpleTaskRunner::PostNonNestableDelayedTask", pt);
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pending_tasks_.insert(pt);
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool OrderedSimpleTaskRunner::RunsTasksOnCurrentThread() const {
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::TimeTicks OrderedSimpleTaskRunner::NextTaskTime() {
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (pending_tasks_.size() <= 0) {
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return TestNowSource::kAbsoluteMaxNow;
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return pending_tasks_.begin()->GetTimeToRun();
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::TimeDelta OrderedSimpleTaskRunner::DelayToNextTaskTime() {
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(thread_checker_.CalledOnValidThread());
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (pending_tasks_.size() <= 0) {
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return TestNowSource::kAbsoluteMaxNow - base::TimeTicks();
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeDelta delay = NextTaskTime() - now_src_->Now();
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (delay > base::TimeDelta())
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return delay;
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return base::TimeDelta();
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst size_t OrderedSimpleTaskRunner::kAbsoluteMaxTasks =
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::numeric_limits<size_t>::max();
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool OrderedSimpleTaskRunner::RunTasksWhile(
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::Callback<bool(void)> condition) {
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<base::Callback<bool(void)> > conditions(1);
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  conditions[0] = condition;
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return RunTasksWhile(conditions);
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool OrderedSimpleTaskRunner::RunTasksWhile(
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::vector<base::Callback<bool(void)> >& conditions) {
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT2("cc",
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "OrderedSimpleTaskRunner::RunPendingTasks",
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "this",
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               AsValue(),
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "nested",
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               inside_run_tasks_until_);
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(thread_checker_.CalledOnValidThread());
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (inside_run_tasks_until_)
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return true;
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::AutoReset<bool> reset_inside_run_tasks_until_(&inside_run_tasks_until_,
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                      true);
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Make a copy so we can append some extra run checks.
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<base::Callback<bool(void)> > modifiable_conditions(conditions);
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Provide a timeout base on number of tasks run so this doesn't loop
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // forever.
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  modifiable_conditions.push_back(TaskRunCountBelow(max_tasks_));
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // If to advance now or not
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!advance_now_) {
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    modifiable_conditions.push_back(NowBefore(now_src_->Now()));
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    modifiable_conditions.push_back(AdvanceNow());
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  while (pending_tasks_.size() > 0) {
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Check if we should continue to run pending tasks.
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool condition_success = true;
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (std::vector<base::Callback<bool(void)> >::iterator it =
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci             modifiable_conditions.begin();
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         it != modifiable_conditions.end();
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         it++) {
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      condition_success = it->Run();
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (!condition_success)
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        break;
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Conditions could modify the pending task length, so we need to recheck
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // that there are tasks to run.
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!condition_success || pending_tasks_.size() == 0) {
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      break;
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::set<TestOrderablePendingTask>::iterator task_to_run =
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        pending_tasks_.begin();
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    {
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TRACE_EVENT1("cc",
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   "OrderedSimpleTaskRunner::RunPendingTasks running",
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   "task",
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   task_to_run->AsValue());
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      task_to_run->task.Run();
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    pending_tasks_.erase(task_to_run);
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return pending_tasks_.size() > 0;
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool OrderedSimpleTaskRunner::RunPendingTasks() {
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return RunTasksWhile(TaskExistedInitially());
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool OrderedSimpleTaskRunner::RunUntilIdle() {
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return RunTasksWhile(std::vector<base::Callback<bool(void)> >());
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool OrderedSimpleTaskRunner::RunUntilTime(base::TimeTicks time) {
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // If we are not auto advancing, force now forward to the time.
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!advance_now_ && now_src_->Now() < time)
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    now_src_->SetNow(time);
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Run tasks
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool result = RunTasksWhile(NowBefore(time));
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // If the next task is after the stopping time and auto-advancing now, then
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // force time to be the stopping time.
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!result && advance_now_ && now_src_->Now() < time) {
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    now_src_->SetNow(time);
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return result;
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool OrderedSimpleTaskRunner::RunForPeriod(base::TimeDelta period) {
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return RunUntilTime(now_src_->Now() + period);
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// base::debug tracing functionality
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_refptr<base::debug::ConvertableToTraceFormat>
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciOrderedSimpleTaskRunner::AsValue() const {
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<base::debug::TracedValue> state =
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new base::debug::TracedValue();
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AsValueInto(state.get());
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return state;
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid OrderedSimpleTaskRunner::AsValueInto(
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::debug::TracedValue* state) const {
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  state->SetInteger("pending_tasks", pending_tasks_.size());
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (std::set<TestOrderablePendingTask>::const_iterator it =
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           pending_tasks_.begin();
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       it != pending_tasks_.end();
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       ++it) {
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    state->BeginDictionary(
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::SizeTToString(std::distance(pending_tasks_.begin(), it)).c_str());
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    it->AsValueInto(state);
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    state->EndDictionary();
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  now_src_->AsValueInto(state);
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::Callback<bool(void)> OrderedSimpleTaskRunner::TaskRunCountBelow(
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    size_t max_tasks) {
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return base::Bind(&OrderedSimpleTaskRunner::TaskRunCountBelowCallback,
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    max_tasks,
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    base::Owned(new size_t(0)));
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool OrderedSimpleTaskRunner::TaskRunCountBelowCallback(size_t max_tasks,
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                        size_t* tasks_run) {
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return (*tasks_run)++ < max_tasks;
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::Callback<bool(void)> OrderedSimpleTaskRunner::TaskExistedInitially() {
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // base::Bind takes a copy of pending_tasks_
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return base::Bind(&OrderedSimpleTaskRunner::TaskExistedInitiallyCallback,
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    base::Unretained(this),
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    pending_tasks_);
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool OrderedSimpleTaskRunner::TaskExistedInitiallyCallback(
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::set<TestOrderablePendingTask>& existing_tasks) {
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return existing_tasks.find(*pending_tasks_.begin()) != existing_tasks.end();
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::Callback<bool(void)> OrderedSimpleTaskRunner::NowBefore(
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::TimeTicks stop_at) {
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return base::Bind(&OrderedSimpleTaskRunner::NowBeforeCallback,
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    base::Unretained(this),
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    stop_at);
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool OrderedSimpleTaskRunner::NowBeforeCallback(base::TimeTicks stop_at) {
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return NextTaskTime() <= stop_at;
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::Callback<bool(void)> OrderedSimpleTaskRunner::AdvanceNow() {
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return base::Bind(&OrderedSimpleTaskRunner::AdvanceNowCallback,
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    base::Unretained(this));
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool OrderedSimpleTaskRunner::AdvanceNowCallback() {
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeTicks next_task_time = NextTaskTime();
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (now_src_->Now() < next_task_time) {
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    now_src_->SetNow(next_task_time);
321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}  // namespace cc
326