low_precision_timer.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // Copyright 2021 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 THIRD_PARTY_BLINK_WEBRTC_OVERRIDES_LOW_PRECISION_TIMER_H_
  5. #define THIRD_PARTY_BLINK_WEBRTC_OVERRIDES_LOW_PRECISION_TIMER_H_
  6. #include "base/callback.h"
  7. #include "base/feature_list.h"
  8. #include "base/memory/ref_counted.h"
  9. #include "base/memory/scoped_refptr.h"
  10. #include "base/synchronization/lock.h"
  11. #include "base/task/sequenced_task_runner.h"
  12. #include "base/thread_annotations.h"
  13. #include "base/time/time.h"
  14. #include "third_party/webrtc/rtc_base/system/rtc_export.h"
  15. #include "third_party/webrtc_overrides/metronome_source.h"
  16. namespace blink {
  17. // Implements a low precision timer, expect it to fire up to ~16 ms late (plus
  18. // any OS or workload related delays).
  19. //
  20. // This timer only fires on metronome ticks as specified by
  21. // MetronomeSource::TimeSnappedToNextTick(). This allows running numerous timers
  22. // without increasing the Idle Wake Ups frequency beyond the metronome tick
  23. // frequency, i.e. when each tick is already scheduled adding a
  24. // LowPrecisionTimer should not add any Idle Wake Ups.
  25. //
  26. // TODO(https://crbug.com/1267874): Can this timer be moved to base/ or replaced
  27. // by a low precision base/ timer without causing excessive Idle Wake Up
  28. // frequencies (e.g. WebRTC use case with 50 incoming videos)?
  29. class RTC_EXPORT LowPrecisionTimer final {
  30. public:
  31. LowPrecisionTimer(scoped_refptr<base::SequencedTaskRunner> task_runner,
  32. base::RepeatingCallback<void()> callback);
  33. ~LowPrecisionTimer();
  34. // Must be called prior to destruction. Unregisters from the metronome
  35. // provider.
  36. void Shutdown();
  37. // Schedules to invoke the callback |delay| time from now.
  38. void StartOneShot(base::TimeDelta delay);
  39. // Scheduldes to repeat unconditionally until the timer is stopped. This has
  40. // the same behavior as calling StartOneShot(delay) inside each callback.
  41. void StartRepeating(base::TimeDelta delay);
  42. // True if there is currently activity scheduled.
  43. bool IsActive();
  44. // Cancels any scheduled callbacks.
  45. void Stop();
  46. // Change which task runner to fire callbacks on. Seamlessy re-schedules
  47. // pending callbacks. Must not be called from inside the callback.
  48. void MoveToNewTaskRunner(
  49. scoped_refptr<base::SequencedTaskRunner> task_runner);
  50. private:
  51. // Handles the scheduling and cancellation of a repeating callback.
  52. // The callback can be re-scheduled after it has fired, but all other settings
  53. // are "const". To change settings the SchedulableCallback has to be
  54. // inactivated and replaced by a new SchedulableCallback instance.
  55. class SchedulableCallback
  56. : public base::RefCountedThreadSafe<SchedulableCallback> {
  57. public:
  58. SchedulableCallback(scoped_refptr<base::SequencedTaskRunner> task_runner,
  59. base::RepeatingCallback<void()> callback,
  60. base::TimeDelta repeated_delay);
  61. ~SchedulableCallback();
  62. // The task can be re-scheduled after each run.
  63. void Schedule(base::TimeTicks scheduled_time);
  64. bool IsScheduled();
  65. // Inactivate the callback. Returns the cancelled scheduled time, or
  66. // base::TimeTicks::Max() if nothing was scheduled when cancelled.
  67. base::TimeTicks Inactivate();
  68. private:
  69. void MaybeRun();
  70. void RemoveMetronomeListener();
  71. const scoped_refptr<base::SequencedTaskRunner> task_runner_;
  72. const base::RepeatingCallback<void()> callback_;
  73. // Only accessed on |task_runner_|.
  74. bool is_currently_running_ = false;
  75. base::Lock active_lock_;
  76. // Guarded by |active_lock_|, but to avoid deadlock we do not acquire the
  77. // lock when Inactivate() is being called from inside the callback. In this
  78. // case the lock is already being held by MaybeRun().
  79. bool is_active_ = true;
  80. base::TimeDelta repeated_delay_;
  81. base::Lock scheduled_time_lock_;
  82. base::TimeTicks scheduled_time_ GUARDED_BY(scheduled_time_lock_) =
  83. base::TimeTicks::Max(); // Max represents forever, i.e. not scheduled.
  84. };
  85. // Lazy-constructs |schedulable_callback_| and schedules the callback on the
  86. // specified time.
  87. void ScheduleCallback(base::TimeTicks scheduled_time)
  88. EXCLUSIVE_LOCKS_REQUIRED(lock_);
  89. // Inactivates in-flight callbacks and re-schedulels the callback using the
  90. // latest settings. Used e.g. when we start or stop using the metronome.
  91. void RescheduleCallback() EXCLUSIVE_LOCKS_REQUIRED(lock_);
  92. const base::RepeatingCallback<void()> callback_;
  93. base::Lock lock_;
  94. bool is_shutdown_ GUARDED_BY(lock_) = false;
  95. scoped_refptr<base::SequencedTaskRunner> task_runner_ GUARDED_BY(lock_);
  96. scoped_refptr<SchedulableCallback> schedulable_callback_ GUARDED_BY(lock_);
  97. // If not repeating this is zero.
  98. base::TimeDelta repeated_delay_ GUARDED_BY(lock_);
  99. };
  100. } // namespace blink
  101. #endif // THIRD_PARTY_BLINK_WEBRTC_OVERRIDES_LOW_PRECISION_TIMER_H_