// Copyright 2017 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 COMPONENTS_POLICY_CORE_COMMON_POLICY_SCHEDULER_H_ #define COMPONENTS_POLICY_CORE_COMMON_POLICY_SCHEDULER_H_ #include #include "base/callback.h" #include "base/cancelable_callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" #include "base/time/time.h" #include "components/policy/policy_export.h" namespace policy { // Scheduler for driving repeated asynchronous tasks such as e.g. policy // fetches. Subsequent tasks are guaranteed not to overlap. Tasks are posted to // the current thread and therefore must not block (suitable e.g. for // asynchronous D-Bus calls). // Tasks scheduling begins immediately after instantiation of the class. Upon // destruction, scheduled but not yet started tasks are cancelled. The result of // started but not finished tasks is NOT reported. class POLICY_EXPORT PolicyScheduler { public: // Callback for the task to report success or failure. using TaskCallback = base::OnceCallback; // Task to be performed at regular intervals. The task takes a |callback| to // return success or failure. using Task = base::RepeatingCallback; // Callback for PolicyScheduler to report success or failure of the tasks. using SchedulerCallback = base::RepeatingCallback; // Defines the |task| to be run every |interval| and the |callback| for the // scheduler to report the result. (Intervals are computed as the time // difference between the end of the previous and the start of the subsequent // task.) Calling the constructor starts the loop and schedules the first task // to be run without delay. PolicyScheduler(Task task, SchedulerCallback callback, base::TimeDelta interval); ~PolicyScheduler(); // Schedules a task to run immediately. Deletes any previously scheduled but // not yet started tasks. In case a task is running currently, the new task is // scheduled to run immediately after the end of the currently running task. void ScheduleTaskNow(); base::TimeDelta interval() const { return interval_; } private: // Schedules next task to run in |delay|. Deletes any previously scheduled // tasks. void ScheduleDelayedTask(base::TimeDelta delay); // Schedules next task to run in |interval_| or immediately in case of // overlap. Deletes any previously scheduled tasks. void ScheduleNextTask(); // Actually executes the scheduled task. void RunScheduledTask(); // Reports back the |result| of the previous task and schedules the next one. void OnTaskDone(bool result); Task task_; SchedulerCallback callback_; // Tasks are being run every |interval_|. const base::TimeDelta interval_; // Whether a task is in progress. bool task_in_progress_ = false; // Whether there had been an overlap of tasks and thus the next task needs to // be scheduled without delay. bool overlap_ = false; // End time of the previous task. Zero in case no task has ended yet. base::TimeTicks last_task_; std::unique_ptr job_; SEQUENCE_CHECKER(sequence_checker_); // Must be last member. base::WeakPtrFactory weak_ptr_factory_{this}; DISALLOW_COPY_AND_ASSIGN(PolicyScheduler); }; } // namespace policy #endif // COMPONENTS_POLICY_CORE_COMMON_POLICY_SCHEDULER_H_