metronome_source.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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_METRONOME_SOURCE_H_
  5. #define THIRD_PARTY_BLINK_WEBRTC_OVERRIDES_METRONOME_SOURCE_H_
  6. #include <atomic>
  7. #include <set>
  8. #include "base/callback.h"
  9. #include "base/memory/ref_counted.h"
  10. #include "base/memory/scoped_refptr.h"
  11. #include "base/synchronization/lock.h"
  12. #include "base/synchronization/waitable_event.h"
  13. #include "base/task/delayed_task_handle.h"
  14. #include "base/thread_annotations.h"
  15. #include "base/time/time.h"
  16. #include "base/timer/timer.h"
  17. #include "third_party/webrtc/api/metronome/metronome.h"
  18. #include "third_party/webrtc/rtc_base/system/rtc_export.h"
  19. namespace blink {
  20. // The MetronomeSource ticks at a constant frequency, scheduling to wake up on
  21. // ticks where listeners have work to do, and not scheduling to wake up on ticks
  22. // where there is no work to do.
  23. //
  24. // When coalescing a large number of wakeup sources onto the MetronomeSource,
  25. // this should reduce package Idle Wake Ups with potential to improve
  26. // performance.
  27. //
  28. // The public API of this class is thread-safe and can be called from any
  29. // sequence.
  30. //
  31. // |webrtc_component| does not have a test binary. See
  32. // /third_party/blink/renderer/platform/peerconnection/metronome_source_test.cc
  33. // for testing.
  34. class RTC_EXPORT MetronomeSource final
  35. : public base::RefCountedThreadSafe<MetronomeSource> {
  36. public:
  37. // Identifies a listener and controls when its callback should be active.
  38. class RTC_EXPORT ListenerHandle
  39. : public base::RefCountedThreadSafe<ListenerHandle> {
  40. public:
  41. ListenerHandle(scoped_refptr<MetronomeSource> metronome_source,
  42. scoped_refptr<base::SequencedTaskRunner> task_runner,
  43. base::RepeatingCallback<void()> callback,
  44. base::TimeTicks wakeup_time);
  45. // Sets the earliest time that the metronome may invoke the listener's
  46. // callback. If set to base::TimeTicks::Min(), the callback is called on
  47. // every metronome tick. If set to anything else, the callback is called a
  48. // single time until SetWakeupTime() is called again.
  49. void SetWakeupTime(base::TimeTicks wakeup_time);
  50. private:
  51. friend class base::RefCountedThreadSafe<ListenerHandle>;
  52. friend class MetronomeSource;
  53. ~ListenerHandle();
  54. void SetWakeUpTimeOnMetronomeTaskRunner(base::TimeTicks wakeup_time);
  55. void OnMetronomeTickOnMetronomeTaskRunner(base::TimeTicks now);
  56. void MaybeRunCallback();
  57. void Inactivate();
  58. const scoped_refptr<MetronomeSource> metronome_source_;
  59. const scoped_refptr<base::SequencedTaskRunner> task_runner_;
  60. const base::RepeatingCallback<void()> callback_;
  61. base::Lock is_active_lock_;
  62. bool is_active_ GUARDED_BY(is_active_lock_) = true;
  63. // The earliest time to fire |callback_|. base::TimeTicks::Min() means to
  64. // fire on every tick, base::TimeTicks::Max() means never to fire.
  65. // Only touched on |metronome_source_->metronome_task_runner_|.
  66. base::TimeTicks wakeup_time_;
  67. };
  68. // The tick phase.
  69. static base::TimeTicks Phase();
  70. // The tick frequency.
  71. static base::TimeDelta Tick();
  72. // The next metronome tick that is at or after |time|.
  73. static base::TimeTicks TimeSnappedToNextTick(base::TimeTicks time);
  74. MetronomeSource();
  75. MetronomeSource(const MetronomeSource&) = delete;
  76. MetronomeSource& operator=(const MetronomeSource&) = delete;
  77. // Creates a new listener whose |callback| will be invoked on |task_runner|.
  78. // If |wakeup_time| is set to base::TimeTicks::Min() then the listener will be
  79. // called on every metronome tick. Otherwise |wakeup_time| is the earliest
  80. // time where the listener will be called a single time, after which
  81. // ListenerHandle::SetWakeupTime() has to be called for the listener to be
  82. // called again.
  83. scoped_refptr<ListenerHandle> AddListener(
  84. scoped_refptr<base::SequencedTaskRunner> task_runner,
  85. base::RepeatingCallback<void()> callback,
  86. base::TimeTicks wakeup_time = base::TimeTicks::Min());
  87. // After this call, the listener's callback is guaranteed not to be running
  88. // and won't ever run again. The listener can be removed from any thread, but
  89. // the listener cannot remove itself from within its own callback.
  90. void RemoveListener(scoped_refptr<ListenerHandle> listener_handle);
  91. // Creates a webrtc::Metronome which is backed by this metronome.
  92. std::unique_ptr<webrtc::Metronome> CreateWebRtcMetronome();
  93. // Ensures the next tick is scheduled and get the time to advance to reach
  94. // that tick. After advancing mock time by the returned time delta, the next
  95. // tick is guaranteed to happen MetronomeTick::Tick() from now.
  96. base::TimeDelta EnsureNextTickAndGetDelayForTesting();
  97. bool HasListenersForTesting();
  98. private:
  99. friend class base::RefCountedThreadSafe<MetronomeSource>;
  100. friend class ListenerHandle;
  101. ~MetronomeSource();
  102. void AddListenerOnMetronomeTaskRunner(
  103. scoped_refptr<ListenerHandle> listener_handle);
  104. void RemoveListenerOnMetronomeTaskRunner(
  105. scoped_refptr<ListenerHandle> listener_handle);
  106. // Ensures the "next tick" is scheduled. The next tick is the next metronome
  107. // tick where we have work to do. If there is no work between now and
  108. // |wakeup_time| we will reschedule such that the next tick happens at or
  109. // after |wakeup_time|, but if there is already a tick scheduled earlier than
  110. // |wakeup_time| this is a NO-OP and more ticks may be needed before
  111. // |wakeup_time| is reached.
  112. void EnsureNextTickIsScheduled(base::TimeTicks wakeup_time);
  113. // |now_tick| is the time that this tick was scheduled to run, so it should be
  114. // very close to base::TimeTicks::Now() but is guaranteed to be aligned with
  115. // the current metronome tick.
  116. void OnMetronomeTick(base::TimeTicks now_tick);
  117. // All non-const members are only accessed on |metronome_task_runner_|.
  118. const scoped_refptr<base::SequencedTaskRunner> metronome_task_runner_;
  119. std::set<scoped_refptr<ListenerHandle>> listeners_;
  120. base::DelayedTaskHandle next_tick_handle_;
  121. base::TimeTicks next_tick_ = base::TimeTicks::Min();
  122. base::TimeTicks prev_tick_;
  123. };
  124. } // namespace blink
  125. #endif // THIRD_PARTY_BLINK_WEBRTC_OVERRIDES_METRONOME_SOURCE_H_