delayed_task_manager.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Copyright 2016 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. #ifndef BASE_TASK_THREAD_POOL_DELAYED_TASK_MANAGER_H_
  5. #define BASE_TASK_THREAD_POOL_DELAYED_TASK_MANAGER_H_
  6. #include <memory>
  7. #include <utility>
  8. #include "base/base_export.h"
  9. #include "base/callback.h"
  10. #include "base/macros.h"
  11. #include "base/memory/ptr_util.h"
  12. #include "base/memory/ref_counted.h"
  13. #include "base/optional.h"
  14. #include "base/synchronization/atomic_flag.h"
  15. #include "base/task/common/checked_lock.h"
  16. #include "base/task/common/intrusive_heap.h"
  17. #include "base/task/thread_pool/task.h"
  18. #include "base/thread_annotations.h"
  19. #include "base/time/default_tick_clock.h"
  20. #include "base/time/tick_clock.h"
  21. namespace base {
  22. class SequencedTaskRunner;
  23. namespace internal {
  24. // The DelayedTaskManager forwards tasks to post task callbacks when they become
  25. // ripe for execution. Tasks are not forwarded before Start() is called. This
  26. // class is thread-safe.
  27. class BASE_EXPORT DelayedTaskManager {
  28. public:
  29. // Posts |task| for execution immediately.
  30. using PostTaskNowCallback = OnceCallback<void(Task task)>;
  31. // |tick_clock| can be specified for testing.
  32. DelayedTaskManager(
  33. const TickClock* tick_clock = DefaultTickClock::GetInstance());
  34. ~DelayedTaskManager();
  35. // Starts the delayed task manager, allowing past and future tasks to be
  36. // forwarded to their callbacks as they become ripe for execution.
  37. // |service_thread_task_runner| posts tasks to the ThreadPool service
  38. // thread.
  39. void Start(scoped_refptr<SequencedTaskRunner> service_thread_task_runner);
  40. // Schedules a call to |post_task_now_callback| with |task| as argument when
  41. // |task| is ripe for execution. |task_runner| is passed to retain a
  42. // reference until |task| is ripe.
  43. void AddDelayedTask(Task task,
  44. PostTaskNowCallback post_task_now_callback,
  45. scoped_refptr<TaskRunner> task_runner);
  46. // Pop and post all the ripe tasks in the delayed task queue.
  47. void ProcessRipeTasks();
  48. // Returns the |delayed_run_time| of the next scheduled task, if any.
  49. Optional<TimeTicks> NextScheduledRunTime() const;
  50. private:
  51. struct DelayedTask {
  52. DelayedTask();
  53. DelayedTask(Task task,
  54. PostTaskNowCallback callback,
  55. scoped_refptr<TaskRunner> task_runner);
  56. DelayedTask(DelayedTask&& other);
  57. ~DelayedTask();
  58. // Required by IntrusiveHeap::insert().
  59. DelayedTask& operator=(DelayedTask&& other);
  60. // Required by IntrusiveHeap.
  61. bool operator<=(const DelayedTask& other) const;
  62. Task task;
  63. PostTaskNowCallback callback;
  64. scoped_refptr<TaskRunner> task_runner;
  65. // True iff the delayed task has been marked as scheduled.
  66. bool IsScheduled() const;
  67. // Mark the delayed task as scheduled. Since the sort key is
  68. // |task.delayed_run_time|, it does not alter sort order when it is called.
  69. void SetScheduled();
  70. // Required by IntrusiveHeap.
  71. void SetHeapHandle(const HeapHandle& handle) {}
  72. // Required by IntrusiveHeap.
  73. void ClearHeapHandle() {}
  74. // Required by IntrusiveHeap.
  75. HeapHandle GetHeapHandle() const { return HeapHandle::Invalid(); }
  76. private:
  77. bool scheduled_ = false;
  78. DISALLOW_COPY_AND_ASSIGN(DelayedTask);
  79. };
  80. // Get the time at which to schedule the next |ProcessRipeTasks()| execution,
  81. // or TimeTicks::Max() if none needs to be scheduled (i.e. no task, or next
  82. // task already scheduled).
  83. TimeTicks GetTimeToScheduleProcessRipeTasksLockRequired()
  84. EXCLUSIVE_LOCKS_REQUIRED(queue_lock_);
  85. // Schedule |ProcessRipeTasks()| on the service thread to be executed at the
  86. // given |process_ripe_tasks_time|, provided the given time is not
  87. // TimeTicks::Max().
  88. void ScheduleProcessRipeTasksOnServiceThread(
  89. TimeTicks process_ripe_tasks_time);
  90. const RepeatingClosure process_ripe_tasks_closure_;
  91. const TickClock* const tick_clock_;
  92. // Synchronizes access to |delayed_task_queue_| and the setting of
  93. // |service_thread_task_runner_|. Once |service_thread_task_runner_| is set,
  94. // it is never modified. It is therefore safe to access
  95. // |service_thread_task_runner_| without synchronization once it is observed
  96. // that it is non-null.
  97. mutable CheckedLock queue_lock_;
  98. scoped_refptr<SequencedTaskRunner> service_thread_task_runner_;
  99. IntrusiveHeap<DelayedTask> delayed_task_queue_ GUARDED_BY(queue_lock_);
  100. DISALLOW_COPY_AND_ASSIGN(DelayedTaskManager);
  101. };
  102. } // namespace internal
  103. } // namespace base
  104. #endif // BASE_TASK_THREAD_POOL_DELAYED_TASK_MANAGER_H_