1 // Copyright 2016 The Chromium Authors 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 BASE_TASK_THREAD_POOL_DELAYED_TASK_MANAGER_H_ 6 #define BASE_TASK_THREAD_POOL_DELAYED_TASK_MANAGER_H_ 7 8 #include <functional> 9 10 #include "base/base_export.h" 11 #include "base/containers/intrusive_heap.h" 12 #include "base/functional/callback.h" 13 #include "base/memory/ptr_util.h" 14 #include "base/memory/raw_ptr.h" 15 #include "base/synchronization/atomic_flag.h" 16 #include "base/task/common/checked_lock.h" 17 #include "base/task/delay_policy.h" 18 #include "base/task/thread_pool/task.h" 19 #include "base/thread_annotations.h" 20 #include "base/time/default_tick_clock.h" 21 #include "base/time/tick_clock.h" 22 #include "third_party/abseil-cpp/absl/types/optional.h" 23 24 namespace base { 25 26 class SequencedTaskRunner; 27 28 namespace internal { 29 30 // The DelayedTaskManager forwards tasks to post task callbacks when they become 31 // ripe for execution. Tasks are not forwarded before Start() is called. This 32 // class is thread-safe. 33 class BASE_EXPORT DelayedTaskManager { 34 public: 35 // Posts |task| for execution immediately. 36 using PostTaskNowCallback = OnceCallback<void(Task task)>; 37 38 // |tick_clock| can be specified for testing. 39 DelayedTaskManager( 40 const TickClock* tick_clock = DefaultTickClock::GetInstance()); 41 DelayedTaskManager(const DelayedTaskManager&) = delete; 42 DelayedTaskManager& operator=(const DelayedTaskManager&) = delete; 43 ~DelayedTaskManager(); 44 45 // Starts the delayed task manager, allowing past and future tasks to be 46 // forwarded to their callbacks as they become ripe for execution. 47 // |service_thread_task_runner| posts tasks to the ThreadPool service 48 // thread. 49 void Start(scoped_refptr<SequencedTaskRunner> service_thread_task_runner); 50 51 // Schedules a call to |post_task_now_callback| with |task| as argument when 52 // |task| is ripe for execution. |task_runner| is passed to retain a 53 // reference until |task| is ripe. 54 void AddDelayedTask(Task task, 55 PostTaskNowCallback post_task_now_callback, 56 scoped_refptr<TaskRunner> task_runner); 57 58 // Pop and post all the ripe tasks in the delayed task queue. 59 void ProcessRipeTasks(); 60 61 // Returns the |delayed_run_time| of the next scheduled task, if any. 62 absl::optional<TimeTicks> NextScheduledRunTime() const; 63 64 // Returns the DelayPolicy for the next delayed task. 65 subtle::DelayPolicy TopTaskDelayPolicyForTesting() const; 66 67 // Must be invoked before deleting the delayed task manager. The caller must 68 // flush tasks posted to the service thread by this before deleting the 69 // delayed task manager. 70 void Shutdown(); 71 72 private: 73 struct DelayedTask { 74 DelayedTask(); 75 DelayedTask(Task task, 76 PostTaskNowCallback callback, 77 scoped_refptr<TaskRunner> task_runner); 78 DelayedTask(DelayedTask&& other); 79 DelayedTask(const DelayedTask&) = delete; 80 DelayedTask& operator=(const DelayedTask&) = delete; 81 ~DelayedTask(); 82 83 // Required by IntrusiveHeap::insert(). 84 DelayedTask& operator=(DelayedTask&& other); 85 86 // Used for a min-heap. 87 bool operator>(const DelayedTask& other) const; 88 89 Task task; 90 PostTaskNowCallback callback; 91 scoped_refptr<TaskRunner> task_runner; 92 93 // Mark the delayed task as scheduled. Since the sort key is 94 // |task.delayed_run_time|, it does not alter sort order when it is called. 95 void SetScheduled(); 96 97 // Required by IntrusiveHeap. SetHeapHandleDelayedTask98 void SetHeapHandle(const HeapHandle& handle) {} 99 100 // Required by IntrusiveHeap. ClearHeapHandleDelayedTask101 void ClearHeapHandle() {} 102 103 // Required by IntrusiveHeap. GetHeapHandleDelayedTask104 HeapHandle GetHeapHandle() const { return HeapHandle::Invalid(); } 105 }; 106 107 // Get the time at which to schedule the next |ProcessRipeTasks()| execution, 108 // or TimeTicks::Max() if none needs to be scheduled (i.e. no task, or next 109 // task already scheduled). 110 std::pair<TimeTicks, subtle::DelayPolicy> 111 GetTimeAndDelayPolicyToScheduleProcessRipeTasksLockRequired() 112 EXCLUSIVE_LOCKS_REQUIRED(queue_lock_); 113 114 // Schedule |ProcessRipeTasks()| on the service thread to be executed when 115 // the next task is ripe. 116 void ScheduleProcessRipeTasksOnServiceThread(); 117 118 const RepeatingClosure process_ripe_tasks_closure_; 119 const RepeatingClosure schedule_process_ripe_tasks_closure_; 120 121 const raw_ptr<const TickClock> tick_clock_; 122 123 // Synchronizes access to |delayed_task_queue_| and the setting of 124 // |service_thread_task_runner_|. Once |service_thread_task_runner_| is set, 125 // it is never modified. It is therefore safe to access 126 // |service_thread_task_runner_| without synchronization once it is observed 127 // that it is non-null. 128 mutable CheckedLock queue_lock_{UniversalSuccessor()}; 129 130 scoped_refptr<SequencedTaskRunner> service_thread_task_runner_; 131 132 DelayedTaskHandle delayed_task_handle_ GUARDED_BY_CONTEXT(sequence_checker_); 133 134 IntrusiveHeap<DelayedTask, std::greater<>> delayed_task_queue_ 135 GUARDED_BY(queue_lock_); 136 137 bool align_wake_ups_ GUARDED_BY(queue_lock_) = false; 138 139 SEQUENCE_CHECKER(sequence_checker_); 140 }; 141 142 } // namespace internal 143 } // namespace base 144 145 #endif // BASE_TASK_THREAD_POOL_DELAYED_TASK_MANAGER_H_ 146