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