Chromium Code Reviews| 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..de1ca8b27ec521e99b7d1e45acc100c1b2704b6d 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,165 @@ 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("function", 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() {} |
| +scoped_refptr<base::debug::ConvertableToTraceFormat> |
| +OrderedSimpleTaskRunner::AsValue() const { |
| + scoped_refptr<base::debug::TracedValue> state = |
| + new base::debug::TracedValue(); |
| + |
| + 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(); |
| + } |
| + return state; |
| +} |
| + |
| +OrderedSimpleTaskRunner::OrderedSimpleTaskRunner(bool advance_now) |
| + : advance_now_(advance_now), now_(), inside_run_pending_tasks_(false) { |
| +} |
| OrderedSimpleTaskRunner::~OrderedSimpleTaskRunner() {} |
|
Sami
2014/08/19 18:45:04
// static
|
| +void OrderedSimpleTaskRunner::SortTasks( |
| + std::deque<base::TestPendingTask>* tasks) { |
| + std::stable_sort(tasks->begin(), tasks->end(), TestPendingTaskComparator); |
| +} |
| + |
| +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(), 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(), delay, base::TestPendingTask::NON_NESTABLE); |
| + |
| + TRACE_TASK("OrderedSimpleTaskRunner::PostNonNestableDelayedTask", pt); |
| + |
| + pending_tasks_.push_back(pt); |
| + SortTasks(&pending_tasks_); |
| + return true; |
| +} |
| + |
| void OrderedSimpleTaskRunner::RunPendingTasks() { |
| + TRACE_EVENT2("cc", |
| + "OrderedSimpleTaskRunner::RunPendingTasks", |
| + "now", |
| + Now(), |
| + "tasks", |
| + 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()) { |
| + if (!advance_now_) |
| + break; |
| + else |
| + 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); |
| + } |
| + std::stable_sort( |
|
Sami
2014/08/19 18:45:04
Can you call SortTasks here?
|
| + pending_tasks_.begin(), pending_tasks_.end(), TestPendingTaskComparator); |
| + |
| + inside_run_pending_tasks_ = false; |
| +} |
| + |
| +base::TimeTicks OrderedSimpleTaskRunner::Now() const { |
| + return now_; |
| +} |
| + |
| +base::TimeDelta OrderedSimpleTaskRunner::DelayToNextPendingTask() { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + |
| + base::TimeDelta delay = pending_tasks_.front().GetTimeToRun() - Now(); |
| + if (delay > base::TimeDelta()) |
| + return delay; |
| + return base::TimeDelta(); |
| +} |
| + |
| +void OrderedSimpleTaskRunner::SetAutoAdvanceNowToPendingTasks( |
| + bool advance_now) { |
| + advance_now_ = advance_now; |
| +} |
| + |
| +void OrderedSimpleTaskRunner::SetNow(base::TimeTicks time) { |
| + TRACE_EVENT_INSTANT2("cc", |
|
Sami
2014/08/19 18:45:04
Random question: can we get traces out of unit tes
|
| + "OrderedSimpleTaskRunner::SetNow", |
| + TRACE_EVENT_SCOPE_THREAD, |
| + "current", |
| + time, |
| + "new", |
| + time); |
| + DCHECK(time >= now_); |
| + now_ = time; |
| } |
| } // namespace cc |