blob: 5f366cb000f41a154aaee3229a1ccd738e517453 [file] [log] [blame]
Sebastian Janssonecb68972019-01-18 10:30:54 +01001/*
2 * Copyright 2019 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "rtc_base/task_utils/repeating_task.h"
12#include "rtc_base/logging.h"
Steve Antonf3802842019-01-24 19:07:40 -080013#include "rtc_base/time_utils.h"
Sebastian Janssonecb68972019-01-18 10:30:54 +010014
15namespace webrtc {
16namespace webrtc_repeating_task_impl {
17RepeatingTaskBase::RepeatingTaskBase(rtc::TaskQueue* task_queue,
18 TimeDelta first_delay)
19 : task_queue_(task_queue),
20 next_run_time_(Timestamp::us(rtc::TimeMicros()) + first_delay) {}
21
22RepeatingTaskBase::~RepeatingTaskBase() = default;
23
24bool RepeatingTaskBase::Run() {
25 RTC_DCHECK_RUN_ON(task_queue_);
26 // Return true to tell the TaskQueue to destruct this object.
27 if (next_run_time_.IsPlusInfinity())
28 return true;
29
30 TimeDelta delay = RunClosure();
31 RTC_DCHECK(delay.IsFinite());
32
33 // The closure might have stopped this task, in which case we return true to
34 // destruct this object.
35 if (next_run_time_.IsPlusInfinity())
36 return true;
37
38 TimeDelta lost_time = Timestamp::us(rtc::TimeMicros()) - next_run_time_;
39 next_run_time_ += delay;
40 delay -= lost_time;
Sebastian Janssona497d122019-02-04 16:39:28 +010041 delay = std::max(delay, TimeDelta::Zero());
Sebastian Janssonecb68972019-01-18 10:30:54 +010042
Sebastian Janssona497d122019-02-04 16:39:28 +010043 task_queue_->PostDelayedTask(absl::WrapUnique(this), delay.ms());
44
Sebastian Janssonecb68972019-01-18 10:30:54 +010045 // Return false to tell the TaskQueue to not destruct this object since we
46 // have taken ownership with absl::WrapUnique.
47 return false;
48}
49
50void RepeatingTaskBase::Stop() {
51 RTC_DCHECK(next_run_time_.IsFinite());
52 next_run_time_ = Timestamp::PlusInfinity();
53}
54
55void RepeatingTaskBase::PostStop() {
56 if (task_queue_->IsCurrent()) {
57 RTC_DLOG(LS_INFO) << "Using PostStop() from the task queue running the "
58 "repeated task. Consider calling Stop() instead.";
59 }
60 task_queue_->PostTask([this] {
61 RTC_DCHECK_RUN_ON(task_queue_);
62 Stop();
63 });
64}
65
66} // namespace webrtc_repeating_task_impl
67RepeatingTaskHandle::RepeatingTaskHandle() {
68 sequence_checker_.Detach();
69}
70RepeatingTaskHandle::~RepeatingTaskHandle() {
71 sequence_checker_.Detach();
72}
73
74RepeatingTaskHandle::RepeatingTaskHandle(RepeatingTaskHandle&& other)
75 : repeating_task_(other.repeating_task_) {
76 RTC_DCHECK_RUN_ON(&sequence_checker_);
77 other.repeating_task_ = nullptr;
78}
79
80RepeatingTaskHandle& RepeatingTaskHandle::operator=(
81 RepeatingTaskHandle&& other) {
82 RTC_DCHECK_RUN_ON(&other.sequence_checker_);
83 {
84 RTC_DCHECK_RUN_ON(&sequence_checker_);
85 repeating_task_ = other.repeating_task_;
86 }
87 other.repeating_task_ = nullptr;
88 return *this;
89}
90
91RepeatingTaskHandle::RepeatingTaskHandle(
92 webrtc_repeating_task_impl::RepeatingTaskBase* repeating_task)
93 : repeating_task_(repeating_task) {}
94
95void RepeatingTaskHandle::Stop() {
96 RTC_DCHECK_RUN_ON(&sequence_checker_);
97 if (repeating_task_) {
98 RTC_DCHECK_RUN_ON(repeating_task_->task_queue_);
99 repeating_task_->Stop();
100 repeating_task_ = nullptr;
101 }
102}
103
104void RepeatingTaskHandle::PostStop() {
105 RTC_DCHECK_RUN_ON(&sequence_checker_);
106 if (repeating_task_) {
107 repeating_task_->PostStop();
108 repeating_task_ = nullptr;
109 }
110}
111
112bool RepeatingTaskHandle::Running() const {
113 RTC_DCHECK_RUN_ON(&sequence_checker_);
114 return repeating_task_ != nullptr;
115}
116
117} // namespace webrtc