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/base/macros.h",
|
||||||
"+absl/cleanup/cleanup.h",
|
"+absl/cleanup/cleanup.h",
|
||||||
"+absl/container/inlined_vector.h",
|
"+absl/container/inlined_vector.h",
|
||||||
|
"+absl/functional/any_invocable.h",
|
||||||
"+absl/functional/bind_front.h",
|
"+absl/functional/bind_front.h",
|
||||||
"+absl/memory/memory.h",
|
"+absl/memory/memory.h",
|
||||||
"+absl/meta/type_traits.h",
|
"+absl/meta/type_traits.h",
|
||||||
|
|||||||
@ -25,6 +25,7 @@ will generate a shared library.
|
|||||||
|
|
||||||
## **Allowed**
|
## **Allowed**
|
||||||
|
|
||||||
|
* `absl::AnyInvocable`
|
||||||
* `absl::bind_front`
|
* `absl::bind_front`
|
||||||
* `absl::Cleanup`
|
* `absl::Cleanup`
|
||||||
* `absl::InlinedVector`
|
* `absl::InlinedVector`
|
||||||
|
|||||||
@ -24,7 +24,10 @@ rtc_library("repeating_task") {
|
|||||||
"../../api/units:timestamp",
|
"../../api/units:timestamp",
|
||||||
"../../system_wrappers:system_wrappers",
|
"../../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") {
|
rtc_library("pending_task_safety_flag") {
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "rtc_base/task_utils/repeating_task.h"
|
#include "rtc_base/task_utils/repeating_task.h"
|
||||||
|
|
||||||
|
#include "absl/functional/any_invocable.h"
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
#include "api/task_queue/pending_task_safety_flag.h"
|
#include "api/task_queue/pending_task_safety_flag.h"
|
||||||
#include "api/task_queue/to_queued_task.h"
|
#include "api/task_queue/to_queued_task.h"
|
||||||
@ -17,29 +18,53 @@
|
|||||||
#include "rtc_base/time_utils.h"
|
#include "rtc_base/time_utils.h"
|
||||||
|
|
||||||
namespace webrtc {
|
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* task_queue,
|
||||||
TaskQueueBase::DelayPrecision precision,
|
TaskQueueBase::DelayPrecision precision,
|
||||||
TimeDelta first_delay,
|
TimeDelta first_delay,
|
||||||
|
absl::AnyInvocable<TimeDelta()> task,
|
||||||
Clock* clock,
|
Clock* clock,
|
||||||
rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag)
|
rtc::scoped_refptr<PendingTaskSafetyFlag> alive_flag)
|
||||||
: task_queue_(task_queue),
|
: task_queue_(task_queue),
|
||||||
precision_(precision),
|
precision_(precision),
|
||||||
clock_(clock),
|
clock_(clock),
|
||||||
|
task_(std::move(task)),
|
||||||
next_run_time_(clock_->CurrentTime() + first_delay),
|
next_run_time_(clock_->CurrentTime() + first_delay),
|
||||||
alive_flag_(std::move(alive_flag)) {}
|
alive_flag_(std::move(alive_flag)) {}
|
||||||
|
|
||||||
RepeatingTaskBase::~RepeatingTaskBase() = default;
|
bool RepeatingTask::Run() {
|
||||||
|
|
||||||
bool RepeatingTaskBase::Run() {
|
|
||||||
RTC_DCHECK_RUN_ON(task_queue_);
|
RTC_DCHECK_RUN_ON(task_queue_);
|
||||||
// Return true to tell the TaskQueue to destruct this object.
|
// Return true to tell the TaskQueue to destruct this object.
|
||||||
if (!alive_flag_->alive())
|
if (!alive_flag_->alive())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
TimeDelta delay = RunClosure();
|
webrtc_repeating_task_impl::RepeatingTaskImplDTraceProbeRun();
|
||||||
|
TimeDelta delay = task_();
|
||||||
RTC_DCHECK_GE(delay, TimeDelta::Zero());
|
RTC_DCHECK_GE(delay, TimeDelta::Zero());
|
||||||
|
|
||||||
// A delay of +infinity means that the task should not be run again.
|
// A delay of +infinity means that the task should not be run again.
|
||||||
@ -61,7 +86,38 @@ bool RepeatingTaskBase::Run() {
|
|||||||
return false;
|
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() {
|
void RepeatingTaskHandle::Stop() {
|
||||||
if (repeating_task_) {
|
if (repeating_task_) {
|
||||||
|
|||||||
@ -15,11 +15,10 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "absl/functional/any_invocable.h"
|
||||||
#include "api/task_queue/pending_task_safety_flag.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/task_queue/task_queue_base.h"
|
||||||
#include "api/units/time_delta.h"
|
#include "api/units/time_delta.h"
|
||||||
#include "api/units/timestamp.h"
|
|
||||||
#include "system_wrappers/include/clock.h"
|
#include "system_wrappers/include/clock.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -31,64 +30,6 @@ void RepeatingTaskHandleDTraceProbeStart();
|
|||||||
void RepeatingTaskHandleDTraceProbeDelayedStart();
|
void RepeatingTaskHandleDTraceProbeDelayedStart();
|
||||||
void RepeatingTaskImplDTraceProbeRun();
|
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
|
} // namespace webrtc_repeating_task_impl
|
||||||
|
|
||||||
// Allows starting tasks that repeat themselves on a TaskQueue indefinately
|
// 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
|
// 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.
|
// task is running, since the repeated task is owned by the TaskQueue.
|
||||||
// The tasks are scheduled onto the task queue using the specified precision.
|
// The tasks are scheduled onto the task queue using the specified precision.
|
||||||
template <class Closure>
|
|
||||||
static RepeatingTaskHandle Start(TaskQueueBase* task_queue,
|
static RepeatingTaskHandle Start(TaskQueueBase* task_queue,
|
||||||
Closure&& closure,
|
absl::AnyInvocable<TimeDelta()> closure,
|
||||||
TaskQueueBase::DelayPrecision precision =
|
TaskQueueBase::DelayPrecision precision =
|
||||||
TaskQueueBase::DelayPrecision::kLow,
|
TaskQueueBase::DelayPrecision::kLow,
|
||||||
Clock* clock = Clock::GetRealTimeClock()) {
|
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
// DelayedStart is equivalent to Start except that the first invocation of the
|
// DelayedStart is equivalent to Start except that the first invocation of the
|
||||||
// closure will be delayed by the given amount.
|
// closure will be delayed by the given amount.
|
||||||
template <class Closure>
|
|
||||||
static RepeatingTaskHandle DelayedStart(
|
static RepeatingTaskHandle DelayedStart(
|
||||||
TaskQueueBase* task_queue,
|
TaskQueueBase* task_queue,
|
||||||
TimeDelta first_delay,
|
TimeDelta first_delay,
|
||||||
Closure&& closure,
|
absl::AnyInvocable<TimeDelta()> closure,
|
||||||
TaskQueueBase::DelayPrecision precision =
|
TaskQueueBase::DelayPrecision precision =
|
||||||
TaskQueueBase::DelayPrecision::kLow,
|
TaskQueueBase::DelayPrecision::kLow,
|
||||||
Clock* clock = Clock::GetRealTimeClock()) {
|
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stops future invocations of the repeating task closure. Can only be called
|
// 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
|
// from the TaskQueue where the task is running. The closure is guaranteed to
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user