Let a RepeatingTask stop itself by returning a delay of PlusInfinity.
Bug: none Change-Id: I5bf87e236019d156ffe85c5b91ce09f5f4042937 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/247160 Reviewed-by: Evan Shrubsole <eshr@webrtc.org> Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/main@{#35710}
This commit is contained in:

committed by
WebRTC LUCI CQ

parent
46cc32d89f
commit
902b55457a
@ -38,13 +38,14 @@ bool RepeatingTaskBase::Run() {
|
||||
return true;
|
||||
|
||||
TimeDelta delay = RunClosure();
|
||||
RTC_DCHECK_GE(delay, TimeDelta::Zero());
|
||||
|
||||
// The closure might have stopped this task, in which case we return true to
|
||||
// destruct this object.
|
||||
if (!alive_flag_->alive())
|
||||
// A delay of +infinity means that the task should not be run again.
|
||||
// Alternatively, the closure might have stopped this task. In either which
|
||||
// case we return true to destruct this object.
|
||||
if (delay.IsPlusInfinity() || !alive_flag_->alive())
|
||||
return true;
|
||||
|
||||
RTC_DCHECK(delay.IsFinite());
|
||||
TimeDelta lost_time = clock_->CurrentTime() - next_run_time_;
|
||||
next_run_time_ += delay;
|
||||
delay -= lost_time;
|
||||
|
@ -52,7 +52,10 @@ class RepeatingTaskBase : public QueuedTask {
|
||||
RTC_GUARDED_BY(task_queue_);
|
||||
};
|
||||
|
||||
// The template closure pattern is based on rtc::ClosureTask.
|
||||
// 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:
|
||||
|
@ -239,34 +239,43 @@ TEST(RepeatingTaskTest, TaskCanStopItself) {
|
||||
EXPECT_EQ(counter.load(), 1);
|
||||
}
|
||||
|
||||
TEST(RepeatingTaskTest, TaskCanStopItselfByReturningInfinity) {
|
||||
std::atomic_int counter(0);
|
||||
SimulatedClock clock(Timestamp::Zero());
|
||||
FakeTaskQueue task_queue(&clock);
|
||||
RepeatingTaskHandle handle = RepeatingTaskHandle::Start(&task_queue, [&] {
|
||||
++counter;
|
||||
return TimeDelta::PlusInfinity();
|
||||
});
|
||||
EXPECT_EQ(task_queue.last_delay(), 0u);
|
||||
// Task cancelled itself so wants to be released.
|
||||
EXPECT_TRUE(task_queue.AdvanceTimeAndRunLastTask());
|
||||
EXPECT_EQ(counter.load(), 1);
|
||||
}
|
||||
|
||||
TEST(RepeatingTaskTest, ZeroReturnValueRepostsTheTask) {
|
||||
NiceMock<MockClosure> closure;
|
||||
rtc::Event done;
|
||||
RepeatingTaskHandle handle;
|
||||
EXPECT_CALL(closure, Call())
|
||||
.WillOnce(Return(TimeDelta::Zero()))
|
||||
.WillOnce(Invoke([&] {
|
||||
done.Set();
|
||||
handle.Stop();
|
||||
return kTimeout;
|
||||
return TimeDelta::PlusInfinity();
|
||||
}));
|
||||
TaskQueueForTest task_queue("queue");
|
||||
handle =
|
||||
RepeatingTaskHandle::Start(task_queue.Get(), MoveOnlyClosure(&closure));
|
||||
RepeatingTaskHandle::Start(task_queue.Get(), MoveOnlyClosure(&closure));
|
||||
EXPECT_TRUE(done.Wait(kTimeout.ms()));
|
||||
}
|
||||
|
||||
TEST(RepeatingTaskTest, StartPeriodicTask) {
|
||||
MockFunction<TimeDelta()> closure;
|
||||
rtc::Event done;
|
||||
RepeatingTaskHandle handle;
|
||||
EXPECT_CALL(closure, Call())
|
||||
.WillOnce(Return(TimeDelta::Millis(20)))
|
||||
.WillOnce(Return(TimeDelta::Millis(20)))
|
||||
.WillOnce(Invoke([&] {
|
||||
done.Set();
|
||||
handle.Stop();
|
||||
return kTimeout;
|
||||
return TimeDelta::PlusInfinity();
|
||||
}));
|
||||
TaskQueueForTest task_queue("queue");
|
||||
RepeatingTaskHandle::Start(task_queue.Get(), closure.AsStdFunction());
|
||||
|
Reference in New Issue
Block a user