| Index: cc/test/ordered_simple_task_runner.cc
|
| diff --git a/cc/test/ordered_simple_task_runner.cc b/cc/test/ordered_simple_task_runner.cc
|
| index 188ffe72b5f8adea6208635d68263b3139811000..de7223efb9e61d6afb220ab15d6f2d9cd4208db5 100644
|
| --- a/cc/test/ordered_simple_task_runner.cc
|
| +++ b/cc/test/ordered_simple_task_runner.cc
|
| @@ -6,8 +6,18 @@
|
|
|
| #include <algorithm>
|
| #include <deque>
|
| +#include <sstream>
|
| +#include <string>
|
|
|
| -#include "base/logging.h"
|
| +#include "base/debug/trace_event.h"
|
| +#include "base/debug/trace_event_argument.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| +
|
| +#define TRACE_TASK(function, task) \
|
| + TRACE_EVENT_INSTANT1( \
|
| + "cc", function, TRACE_EVENT_SCOPE_THREAD, "task", TaskAsValue(task));
|
| +
|
| +#define TRACE_TASK_RUN(function, tag, task)
|
|
|
| namespace {
|
|
|
| @@ -16,26 +26,166 @@ bool TestPendingTaskComparator(const base::TestPendingTask& lhs,
|
| return lhs.ShouldRunBefore(rhs);
|
| }
|
|
|
| +void TaskAsValueInto(const base::TestPendingTask& task,
|
| + base::debug::TracedValue* state) {
|
| + state->SetInteger("run_at", task.GetTimeToRun().ToInternalValue());
|
| + state->SetString("posted_from", task.location.ToString());
|
| }
|
|
|
| +scoped_refptr<base::debug::ConvertableToTraceFormat> TaskAsValue(
|
| + const base::TestPendingTask& task) {
|
| + scoped_refptr<base::debug::TracedValue> state =
|
| + new base::debug::TracedValue();
|
| + TaskAsValueInto(task, state);
|
| + return state;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| namespace cc {
|
|
|
| -OrderedSimpleTaskRunner::OrderedSimpleTaskRunner() {}
|
| +void OrderedSimpleTaskRunner::SortTasks(
|
| + std::deque<base::TestPendingTask>* tasks) {
|
| + std::stable_sort(tasks->begin(), tasks->end(), TestPendingTaskComparator);
|
| +}
|
| +
|
| +OrderedSimpleTaskRunner::OrderedSimpleTaskRunner()
|
| + : advance_now_(true),
|
| + now_src_(TestNowSource::Create()),
|
| + inside_run_pending_tasks_(false) {
|
| +}
|
| +
|
| +OrderedSimpleTaskRunner::OrderedSimpleTaskRunner(
|
| + scoped_refptr<TestNowSource> now_src,
|
| + bool advance_now)
|
| + : advance_now_(advance_now),
|
| + now_src_(now_src),
|
| + inside_run_pending_tasks_(false) {
|
| +}
|
|
|
| OrderedSimpleTaskRunner::~OrderedSimpleTaskRunner() {}
|
|
|
| +// base::TestSimpleTaskRunner implementation
|
| +bool OrderedSimpleTaskRunner::PostDelayedTask(
|
| + const tracked_objects::Location& from_here,
|
| + const base::Closure& task,
|
| + base::TimeDelta delay) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + base::TestPendingTask pt(
|
| + from_here, task, now_src_->Now(), delay, base::TestPendingTask::NESTABLE);
|
| +
|
| + TRACE_TASK("OrderedSimpleTaskRunner::PostDelayedTask", pt);
|
| +
|
| + pending_tasks_.push_back(pt);
|
| + SortTasks(&pending_tasks_);
|
| + return true;
|
| +}
|
| +
|
| +bool OrderedSimpleTaskRunner::PostNonNestableDelayedTask(
|
| + const tracked_objects::Location& from_here,
|
| + const base::Closure& task,
|
| + base::TimeDelta delay) {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| + base::TestPendingTask pt(from_here,
|
| + task,
|
| + now_src_->Now(),
|
| + delay,
|
| + base::TestPendingTask::NON_NESTABLE);
|
| +
|
| + TRACE_TASK("OrderedSimpleTaskRunner::PostNonNestableDelayedTask", pt);
|
| +
|
| + pending_tasks_.push_back(pt);
|
| + SortTasks(&pending_tasks_);
|
| + return true;
|
| +}
|
| +
|
| void OrderedSimpleTaskRunner::RunPendingTasks() {
|
| + TRACE_EVENT1(
|
| + "cc", "OrderedSimpleTaskRunner::RunPendingTasks", "this", AsValue());
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + if (inside_run_pending_tasks_)
|
| + return;
|
| + inside_run_pending_tasks_ = true;
|
| +
|
| // Swap with a local variable to avoid re-entrancy problems.
|
| std::deque<base::TestPendingTask> tasks_to_run;
|
| tasks_to_run.swap(pending_tasks_);
|
| - std::stable_sort(tasks_to_run.begin(),
|
| - tasks_to_run.end(),
|
| - TestPendingTaskComparator);
|
| - for (std::deque<base::TestPendingTask>::iterator it = tasks_to_run.begin();
|
| - it != tasks_to_run.end(); ++it) {
|
| - it->task.Run();
|
| +
|
| + std::deque<base::TestPendingTask>::iterator it = tasks_to_run.begin();
|
| + for (; it != tasks_to_run.end(); ++it) {
|
| + base::TimeTicks task_time = it->GetTimeToRun();
|
| +
|
| + // Have new items been added to pending_tasks which need to run before this
|
| + // task?
|
| + if (pending_tasks_.size() > 0 &&
|
| + task_time > pending_tasks_.begin()->GetTimeToRun()) {
|
| + break;
|
| + }
|
| +
|
| + // Is the task in the future?
|
| + if (task_time > now_src_->Now()) {
|
| + if (!advance_now_)
|
| + break;
|
| + else
|
| + now_src_->SetNow(task_time);
|
| + }
|
| +
|
| + {
|
| + TRACE_EVENT1("cc",
|
| + "OrderedSimpleTaskRunner::RunPendingTasks running",
|
| + "task",
|
| + TaskAsValue(*it));
|
| + it->task.Run();
|
| + }
|
| + }
|
| +
|
| + // Push any remaining tasks back into the pending queue
|
| + for (; it != tasks_to_run.end(); ++it) {
|
| + pending_tasks_.push_front(*it);
|
| + }
|
| + SortTasks(&pending_tasks_);
|
| +
|
| + inside_run_pending_tasks_ = false;
|
| +}
|
| +
|
| +base::TimeDelta OrderedSimpleTaskRunner::DelayToNextPendingTask() {
|
| + DCHECK(thread_checker_.CalledOnValidThread());
|
| +
|
| + base::TimeDelta delay =
|
| + pending_tasks_.front().GetTimeToRun() - now_src_->Now();
|
| + if (delay > base::TimeDelta())
|
| + return delay;
|
| + return base::TimeDelta();
|
| +}
|
| +
|
| +void OrderedSimpleTaskRunner::SetAutoAdvanceNowToPendingTasks(
|
| + bool advance_now) {
|
| + advance_now_ = advance_now;
|
| +}
|
| +
|
| +// base::debug tracing functionality
|
| +scoped_refptr<base::debug::ConvertableToTraceFormat>
|
| +OrderedSimpleTaskRunner::AsValue() const {
|
| + scoped_refptr<base::debug::TracedValue> state =
|
| + new base::debug::TracedValue();
|
| + AsValueInto(state);
|
| + return state;
|
| +}
|
| +
|
| +void OrderedSimpleTaskRunner::AsValueInto(
|
| + base::debug::TracedValue* state) const {
|
| + state->SetInteger("pending_tasks", pending_tasks_.size());
|
| + for (std::deque<base::TestPendingTask>::const_iterator it =
|
| + pending_tasks_.begin();
|
| + it != pending_tasks_.end();
|
| + ++it) {
|
| + state->BeginDictionary(
|
| + base::SizeTToString(std::distance(pending_tasks_.begin(), it)).c_str());
|
| + TaskAsValueInto(*it, state);
|
| + state->EndDictionary();
|
| }
|
| + now_src_->AsValueInto(state);
|
| }
|
|
|
| } // namespace cc
|
|
|