diff options
-rw-r--r-- | DEPS | 1 | ||||
-rw-r--r-- | g3doc/abseil-in-webrtc.md | 1 | ||||
-rw-r--r-- | rtc_base/task_utils/BUILD.gn | 5 | ||||
-rw-r--r-- | rtc_base/task_utils/repeating_task.cc | 70 | ||||
-rw-r--r-- | rtc_base/task_utils/repeating_task.h | 91 |
5 files changed, 74 insertions, 94 deletions
@@ -2494,6 +2494,7 @@ include_rules = [ "+absl/base/macros.h", "+absl/cleanup/cleanup.h", "+absl/container/inlined_vector.h", + "+absl/functional/any_invocable.h", "+absl/functional/bind_front.h", "+absl/memory/memory.h", "+absl/meta/type_traits.h", diff --git a/g3doc/abseil-in-webrtc.md b/g3doc/abseil-in-webrtc.md index 6f0b4812e8..8561975340 100644 --- a/g3doc/abseil-in-webrtc.md +++ b/g3doc/abseil-in-webrtc.md @@ -25,6 +25,7 @@ will generate a shared library. ## **Allowed** +* `absl::AnyInvocable` * `absl::bind_front` * `absl::Cleanup` * `absl::InlinedVector` diff --git a/rtc_base/task_utils/BUILD.gn b/rtc_base/task_utils/BUILD.gn index 04960b2d29..c01e82e81e 100644 --- a/rtc_base/task_utils/BUILD.gn +++ b/rtc_base/task_utils/BUILD.gn @@ -24,7 +24,10 @@ rtc_library("repeating_task") { "../../api/units:timestamp", "../../system_wrappers:system_wrappers", ] - absl_deps = [ "//third_party/abseil-cpp/absl/memory" ] + absl_deps = [ + "//third_party/abseil-cpp/absl/functional:any_invocable", + "//third_party/abseil-cpp/absl/memory", + ] } rtc_library("pending_task_safety_flag") { diff --git a/rtc_base/task_utils/repeating_task.cc b/rtc_base/task_utils/repeating_task.cc index fc19b9915d..fa6ae79321 100644 --- a/rtc_base/task_utils/repeating_task.cc +++ b/rtc_base/task_utils/repeating_task.cc @@ -10,6 +10,7 @@ #include "rtc_base/task_utils/repeating_task.h" +#include "absl/functional/any_invocable.h" #include "absl/memory/memory.h" #include "api/task_queue/pending_task_safety_flag.h" #include "api/task_queue/to_queued_task.h" @@ -17,29 +18,53 @@ #include "rtc_base/time_utils.h" namespace webrtc { -namespace webrtc_repeating_task_impl { +namespace { + +class RepeatingTask : public QueuedTask { + public: + RepeatingTask(TaskQueueBase* task_queue, + TaskQueueBase::DelayPrecision precision, + TimeDelta first_delay, + absl::AnyInvocable<TimeDelta()> task, + Clock* clock, + rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag); + ~RepeatingTask() override = default; + + private: + bool Run() final; + + TaskQueueBase* const task_queue_; + const TaskQueueBase::DelayPrecision precision_; + Clock* const clock_; + absl::AnyInvocable<TimeDelta()> task_; + // This is always finite. + Timestamp next_run_time_ RTC_GUARDED_BY(task_queue_); + rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag_ + RTC_GUARDED_BY(task_queue_); +}; -RepeatingTaskBase::RepeatingTaskBase( +RepeatingTask::RepeatingTask( TaskQueueBase* task_queue, TaskQueueBase::DelayPrecision precision, TimeDelta first_delay, + absl::AnyInvocable<TimeDelta()> task, Clock* clock, rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag) : task_queue_(task_queue), precision_(precision), clock_(clock), + task_(std::move(task)), next_run_time_(clock_->CurrentTime() + first_delay), alive_flag_(std::move(alive_flag)) {} -RepeatingTaskBase::~RepeatingTaskBase() = default; - -bool RepeatingTaskBase::Run() { +bool RepeatingTask::Run() { RTC_DCHECK_RUN_ON(task_queue_); // Return true to tell the TaskQueue to destruct this object. if (!alive_flag_->alive()) return true; - TimeDelta delay = RunClosure(); + webrtc_repeating_task_impl::RepeatingTaskImplDTraceProbeRun(); + TimeDelta delay = task_(); RTC_DCHECK_GE(delay, TimeDelta::Zero()); // A delay of +infinity means that the task should not be run again. @@ -61,7 +86,38 @@ bool RepeatingTaskBase::Run() { return false; } -} // namespace webrtc_repeating_task_impl +} // namespace + +RepeatingTaskHandle RepeatingTaskHandle::Start( + TaskQueueBase* task_queue, + absl::AnyInvocable<TimeDelta()> closure, + TaskQueueBase::DelayPrecision precision, + Clock* clock) { + auto alive_flag = PendingTaskSafetyFlag::CreateDetached(); + webrtc_repeating_task_impl::RepeatingTaskHandleDTraceProbeStart(); + task_queue->PostTask( + std::make_unique<RepeatingTask>(task_queue, precision, TimeDelta::Zero(), + std::move(closure), clock, alive_flag)); + return RepeatingTaskHandle(std::move(alive_flag)); +} + +// DelayedStart is equivalent to Start except that the first invocation of the +// closure will be delayed by the given amount. +RepeatingTaskHandle RepeatingTaskHandle::DelayedStart( + TaskQueueBase* task_queue, + TimeDelta first_delay, + absl::AnyInvocable<TimeDelta()> closure, + TaskQueueBase::DelayPrecision precision, + Clock* clock) { + auto alive_flag = PendingTaskSafetyFlag::CreateDetached(); + webrtc_repeating_task_impl::RepeatingTaskHandleDTraceProbeDelayedStart(); + task_queue->PostDelayedTaskWithPrecision( + precision, + std::make_unique<RepeatingTask>(task_queue, precision, first_delay, + std::move(closure), clock, alive_flag), + first_delay.ms()); + return RepeatingTaskHandle(std::move(alive_flag)); +} void RepeatingTaskHandle::Stop() { if (repeating_task_) { diff --git a/rtc_base/task_utils/repeating_task.h b/rtc_base/task_utils/repeating_task.h index 4d2b7eb1a2..e5ea3d8174 100644 --- a/rtc_base/task_utils/repeating_task.h +++ b/rtc_base/task_utils/repeating_task.h @@ -15,11 +15,10 @@ #include <type_traits> #include <utility> +#include "absl/functional/any_invocable.h" #include "api/task_queue/pending_task_safety_flag.h" -#include "api/task_queue/queued_task.h" #include "api/task_queue/task_queue_base.h" #include "api/units/time_delta.h" -#include "api/units/timestamp.h" #include "system_wrappers/include/clock.h" namespace webrtc { @@ -31,64 +30,6 @@ void RepeatingTaskHandleDTraceProbeStart(); void RepeatingTaskHandleDTraceProbeDelayedStart(); void RepeatingTaskImplDTraceProbeRun(); -class RepeatingTaskBase : public QueuedTask { - public: - RepeatingTaskBase(TaskQueueBase* task_queue, - TaskQueueBase::DelayPrecision precision, - TimeDelta first_delay, - Clock* clock, - rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag); - ~RepeatingTaskBase() override; - - private: - virtual TimeDelta RunClosure() = 0; - - bool Run() final; - - TaskQueueBase* const task_queue_; - const TaskQueueBase::DelayPrecision precision_; - Clock* const clock_; - // This is always finite. - Timestamp next_run_time_ RTC_GUARDED_BY(task_queue_); - rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag_ - RTC_GUARDED_BY(task_queue_); -}; - -// The template closure pattern is based on rtc::ClosureTask. The provided -// closure should have a TimeDelta return value, specifing the desired -// non-negative interval to next repetition, or TimeDelta::PlusInfinity to -// indicate that the task should be deleted and not called again. -template <class Closure> -class RepeatingTaskImpl final : public RepeatingTaskBase { - public: - RepeatingTaskImpl(TaskQueueBase* task_queue, - TaskQueueBase::DelayPrecision precision, - TimeDelta first_delay, - Closure&& closure, - Clock* clock, - rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag) - : RepeatingTaskBase(task_queue, - precision, - first_delay, - clock, - std::move(alive_flag)), - closure_(std::forward<Closure>(closure)) { - static_assert( - std::is_same<TimeDelta, - typename std::invoke_result<decltype(&Closure::operator()), - Closure>::type>::value, - ""); - } - - private: - TimeDelta RunClosure() override { - RepeatingTaskImplDTraceProbeRun(); - return closure_(); - } - - typename std::remove_const< - typename std::remove_reference<Closure>::type>::type closure_; -}; } // namespace webrtc_repeating_task_impl // Allows starting tasks that repeat themselves on a TaskQueue indefinately @@ -111,43 +52,21 @@ class RepeatingTaskHandle { // TaskQueue deletes it. It's perfectly fine to destroy the handle while the // task is running, since the repeated task is owned by the TaskQueue. // The tasks are scheduled onto the task queue using the specified precision. - template <class Closure> static RepeatingTaskHandle Start(TaskQueueBase* task_queue, - Closure&& closure, + absl::AnyInvocable<TimeDelta()> closure, TaskQueueBase::DelayPrecision precision = TaskQueueBase::DelayPrecision::kLow, - Clock* clock = Clock::GetRealTimeClock()) { - auto alive_flag = PendingTaskSafetyFlag::CreateDetached(); - webrtc_repeating_task_impl::RepeatingTaskHandleDTraceProbeStart(); - task_queue->PostTask( - std::make_unique< - webrtc_repeating_task_impl::RepeatingTaskImpl<Closure>>( - task_queue, precision, TimeDelta::Zero(), - std::forward<Closure>(closure), clock, alive_flag)); - return RepeatingTaskHandle(std::move(alive_flag)); - } + Clock* clock = Clock::GetRealTimeClock()); // DelayedStart is equivalent to Start except that the first invocation of the // closure will be delayed by the given amount. - template <class Closure> static RepeatingTaskHandle DelayedStart( TaskQueueBase* task_queue, TimeDelta first_delay, - Closure&& closure, + absl::AnyInvocable<TimeDelta()> closure, TaskQueueBase::DelayPrecision precision = TaskQueueBase::DelayPrecision::kLow, - Clock* clock = Clock::GetRealTimeClock()) { - auto alive_flag = PendingTaskSafetyFlag::CreateDetached(); - webrtc_repeating_task_impl::RepeatingTaskHandleDTraceProbeDelayedStart(); - task_queue->PostDelayedTaskWithPrecision( - precision, - std::make_unique< - webrtc_repeating_task_impl::RepeatingTaskImpl<Closure>>( - task_queue, precision, first_delay, std::forward<Closure>(closure), - clock, alive_flag), - first_delay.ms()); - return RepeatingTaskHandle(std::move(alive_flag)); - } + Clock* clock = Clock::GetRealTimeClock()); // Stops future invocations of the repeating task closure. Can only be called // from the TaskQueue where the task is running. The closure is guaranteed to |