1 // Copyright 2017 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_POLICY_CORE_COMMON_POLICY_SCHEDULER_H_ 6 #define COMPONENTS_POLICY_CORE_COMMON_POLICY_SCHEDULER_H_ 7 8 #include <memory> 9 10 #include "base/callback.h" 11 #include "base/cancelable_callback.h" 12 #include "base/macros.h" 13 #include "base/memory/weak_ptr.h" 14 #include "base/sequence_checker.h" 15 #include "base/time/time.h" 16 #include "components/policy/policy_export.h" 17 18 namespace policy { 19 20 // Scheduler for driving repeated asynchronous tasks such as e.g. policy 21 // fetches. Subsequent tasks are guaranteed not to overlap. Tasks are posted to 22 // the current thread and therefore must not block (suitable e.g. for 23 // asynchronous D-Bus calls). 24 // Tasks scheduling begins immediately after instantiation of the class. Upon 25 // destruction, scheduled but not yet started tasks are cancelled. The result of 26 // started but not finished tasks is NOT reported. 27 class POLICY_EXPORT PolicyScheduler { 28 public: 29 // Callback for the task to report success or failure. 30 using TaskCallback = base::OnceCallback<void(bool success)>; 31 32 // Task to be performed at regular intervals. The task takes a |callback| to 33 // return success or failure. 34 using Task = base::RepeatingCallback<void(TaskCallback callback)>; 35 36 // Callback for PolicyScheduler to report success or failure of the tasks. 37 using SchedulerCallback = base::RepeatingCallback<void(bool success)>; 38 39 // Defines the |task| to be run every |interval| and the |callback| for the 40 // scheduler to report the result. (Intervals are computed as the time 41 // difference between the end of the previous and the start of the subsequent 42 // task.) Calling the constructor starts the loop and schedules the first task 43 // to be run without delay. 44 PolicyScheduler(Task task, 45 SchedulerCallback callback, 46 base::TimeDelta interval); 47 ~PolicyScheduler(); 48 49 // Schedules a task to run immediately. Deletes any previously scheduled but 50 // not yet started tasks. In case a task is running currently, the new task is 51 // scheduled to run immediately after the end of the currently running task. 52 void ScheduleTaskNow(); 53 interval()54 base::TimeDelta interval() const { return interval_; } 55 56 private: 57 // Schedules next task to run in |delay|. Deletes any previously scheduled 58 // tasks. 59 void ScheduleDelayedTask(base::TimeDelta delay); 60 61 // Schedules next task to run in |interval_| or immediately in case of 62 // overlap. Deletes any previously scheduled tasks. 63 void ScheduleNextTask(); 64 65 // Actually executes the scheduled task. 66 void RunScheduledTask(); 67 68 // Reports back the |result| of the previous task and schedules the next one. 69 void OnTaskDone(bool result); 70 71 Task task_; 72 SchedulerCallback callback_; 73 // Tasks are being run every |interval_|. 74 const base::TimeDelta interval_; 75 76 // Whether a task is in progress. 77 bool task_in_progress_ = false; 78 79 // Whether there had been an overlap of tasks and thus the next task needs to 80 // be scheduled without delay. 81 bool overlap_ = false; 82 83 // End time of the previous task. Zero in case no task has ended yet. 84 base::TimeTicks last_task_; 85 86 std::unique_ptr<base::CancelableClosure> job_; 87 88 SEQUENCE_CHECKER(sequence_checker_); 89 90 // Must be last member. 91 base::WeakPtrFactory<PolicyScheduler> weak_ptr_factory_{this}; 92 93 DISALLOW_COPY_AND_ASSIGN(PolicyScheduler); 94 }; 95 96 } // namespace policy 97 98 #endif // COMPONENTS_POLICY_CORE_COMMON_POLICY_SCHEDULER_H_ 99