Refactor RepeatingTaskHandle to use absl::AnyInvocable
Allow to use AnyInvocable in webrtc. Demonstrate how AnyInvocable can make interface clearer to read and implement Demonstrate that AnyInvocable can reduce binary size Bug: None Change-Id: I33cf33fac6ed3bf4c5e46077d1cd984ca0f253a3 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/267165 Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/main@{#37380}
This commit is contained in:
parent
978cb6762f
commit
4b97928b30
1
DEPS
1
DEPS
@ -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",
|
||||
|
||||
@ -25,6 +25,7 @@ will generate a shared library.
|
||||
|
||||
## **Allowed**
|
||||
|
||||
* `absl::AnyInvocable`
|
||||
* `absl::bind_front`
|
||||
* `absl::Cleanup`
|
||||
* `absl::InlinedVector`
|
||||
|
||||
@ -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") {
|
||||
|
||||
@ -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 {
|
||||
|
||||
RepeatingTaskBase::RepeatingTaskBase(
|
||||
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_);
|
||||
};
|
||||
|
||||
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_) {
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user