// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CC_TEST_ORDERED_SIMPLE_TASK_RUNNER_H_ #define CC_TEST_ORDERED_SIMPLE_TASK_RUNNER_H_ #include #include #include #include #include "base/compiler_specific.h" #include "base/logging.h" #include "base/macros.h" #include "base/test/simple_test_tick_clock.h" #include "base/test/test_simple_task_runner.h" #include "base/trace_event/trace_event.h" namespace cc { // Subclass of TestPendingTask which has a unique ID for every task, supports // being used inside a std::set and has debug tracing support. class TestOrderablePendingTask : public base::TestPendingTask { public: TestOrderablePendingTask(); TestOrderablePendingTask(const tracked_objects::Location& location, const base::Closure& task, base::TimeTicks post_time, base::TimeDelta delay, TestNestability nestability); ~TestOrderablePendingTask(); // operators needed by std::set and comparison bool operator==(const TestOrderablePendingTask& other) const; bool operator<(const TestOrderablePendingTask& other) const; // base::trace_event tracing functionality scoped_refptr AsValue() const; void AsValueInto(base::trace_event::TracedValue* state) const; private: static size_t task_id_counter; const size_t task_id_; }; // This runs pending tasks based on task's post_time + delay. // We should not execute a delayed task sooner than some of the queued tasks // which don't have a delay even though it is queued early. class OrderedSimpleTaskRunner : public base::SingleThreadTaskRunner { public: OrderedSimpleTaskRunner(base::SimpleTestTickClock* now_src, bool advance_now); // base::TestSimpleTaskRunner implementation: bool PostDelayedTask(const tracked_objects::Location& from_here, const base::Closure& task, base::TimeDelta delay) override; bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, const base::Closure& task, base::TimeDelta delay) override; bool RunsTasksOnCurrentThread() const override; static base::TimeTicks AbsoluteMaxNow(); // Set a maximum number of tasks to run at once. Useful as a timeout to // prevent infinite task loops. static const size_t kAbsoluteMaxTasks; void SetRunTaskLimit(size_t max_tasks) { max_tasks_ = max_tasks; } void ClearRunTaskLimit() { max_tasks_ = kAbsoluteMaxTasks; } // Allow task runner to advance now when running tasks. void SetAutoAdvanceNowToPendingTasks(bool advance_now) { advance_now_ = advance_now; } size_t NumPendingTasks() const; bool HasPendingTasks() const; base::TimeTicks NextTaskTime(); base::TimeDelta DelayToNextTaskTime(); // Run tasks while the callback returns true or too many tasks have been run. // Returns true if there are still pending tasks left. bool RunTasksWhile(base::Callback condition); // Run tasks while *all* of the callbacks return true or too many tasks have // been run. Exits on the *first* condition which returns false, skipping // calling all remaining conditions. Conditions can have side effects, // including modifying the task queue. // Returns true if there are still pending tasks left. bool RunTasksWhile(const std::vector>& conditions); // Convenience functions to run tasks with common conditions. // Run tasks which existed at the start of this call. // Return code indicates tasks still exist to run. bool RunPendingTasks(); // Keep running tasks until no tasks are left. // Return code indicates tasks still exist to run which also indicates if // runner reached idle. bool RunUntilIdle(); // Keep running tasks until given time period. // Return code indicates tasks still exist to run. bool RunUntilTime(base::TimeTicks time); bool RunForPeriod(base::TimeDelta period); // base::trace_event tracing functionality scoped_refptr AsValue() const; virtual void AsValueInto(base::trace_event::TracedValue* state) const; // Common conditions to run for, exposed publicly to allow external users to // use their own combinations. // ------------------------------------------------------------------------- // Keep running until the given number of tasks have run. // You generally shouldn't use this check as it will cause your tests to fail // when code is changed adding a new task. It is useful as a "timeout" type // solution. base::Callback TaskRunCountBelow(size_t max_tasks); // Keep running until a task which didn't exist initially would run. base::Callback TaskExistedInitially(); // Stop running tasks when NextTaskTime() >= stop_at base::Callback NowBefore(base::TimeTicks stop_at); // Advance Now() to the next task to run. base::Callback AdvanceNow(); protected: static bool TaskRunCountBelowCallback(size_t max_tasks, size_t* task_run); bool TaskExistedInitiallyCallback( const std::set& existing_tasks); bool NowBeforeCallback(base::TimeTicks stop_at); bool AdvanceNowCallback(); ~OrderedSimpleTaskRunner() override; base::ThreadChecker thread_checker_; bool advance_now_; // Not owned. base::SimpleTestTickClock* now_src_; size_t max_tasks_; bool inside_run_tasks_until_; std::set pending_tasks_; private: DISALLOW_COPY_AND_ASSIGN(OrderedSimpleTaskRunner); }; } // namespace cc #endif // CC_TEST_ORDERED_SIMPLE_TASK_RUNNER_H_