123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- /*
- * Copyright 2019 The WebRTC Project Authors. All rights reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
- #ifndef RTC_BASE_TASK_UTILS_REPEATING_TASK_H_
- #define RTC_BASE_TASK_UTILS_REPEATING_TASK_H_
- #include <memory>
- #include <type_traits>
- #include <utility>
- #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 {
- class RepeatingTaskHandle;
- namespace webrtc_repeating_task_impl {
- class RepeatingTaskBase : public QueuedTask {
- public:
- RepeatingTaskBase(TaskQueueBase* task_queue,
- TimeDelta first_delay,
- Clock* clock);
- ~RepeatingTaskBase() override;
- void Stop();
- private:
- virtual TimeDelta RunClosure() = 0;
- bool Run() final;
- TaskQueueBase* const task_queue_;
- Clock* const clock_;
- // This is always finite, except for the special case where it's PlusInfinity
- // to signal that the task should stop.
- Timestamp next_run_time_ RTC_GUARDED_BY(task_queue_);
- };
- // The template closure pattern is based on rtc::ClosureTask.
- template <class Closure>
- class RepeatingTaskImpl final : public RepeatingTaskBase {
- public:
- RepeatingTaskImpl(TaskQueueBase* task_queue,
- TimeDelta first_delay,
- Closure&& closure,
- Clock* clock)
- : RepeatingTaskBase(task_queue, first_delay, clock),
- closure_(std::forward<Closure>(closure)) {
- static_assert(
- std::is_same<TimeDelta,
- typename std::result_of<decltype (&Closure::operator())(
- Closure)>::type>::value,
- "");
- }
- private:
- TimeDelta RunClosure() override { 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
- // until they are stopped or the TaskQueue is destroyed. It allows starting and
- // stopping multiple times, but you must stop one task before starting another
- // and it can only be stopped when in the running state. The public interface is
- // not thread safe.
- class RepeatingTaskHandle {
- public:
- RepeatingTaskHandle() = default;
- ~RepeatingTaskHandle() = default;
- RepeatingTaskHandle(RepeatingTaskHandle&& other);
- RepeatingTaskHandle& operator=(RepeatingTaskHandle&& other);
- RepeatingTaskHandle(const RepeatingTaskHandle&) = delete;
- RepeatingTaskHandle& operator=(const RepeatingTaskHandle&) = delete;
- // Start can be used to start a task that will be reposted with a delay
- // determined by the return value of the provided closure. The actual task is
- // owned by the TaskQueue and will live until it has been stopped or the
- // TaskQueue is destroyed. Note that this means that trying to stop the
- // repeating task after the TaskQueue is destroyed is an error. However, it's
- // perfectly fine to destroy the handle while the task is running, since the
- // repeated task is owned by the TaskQueue.
- template <class Closure>
- static RepeatingTaskHandle Start(TaskQueueBase* task_queue,
- Closure&& closure,
- Clock* clock = Clock::GetRealTimeClock()) {
- auto repeating_task = std::make_unique<
- webrtc_repeating_task_impl::RepeatingTaskImpl<Closure>>(
- task_queue, TimeDelta::Zero(), std::forward<Closure>(closure), clock);
- auto* repeating_task_ptr = repeating_task.get();
- task_queue->PostTask(std::move(repeating_task));
- return RepeatingTaskHandle(repeating_task_ptr);
- }
- // 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,
- Clock* clock = Clock::GetRealTimeClock()) {
- auto repeating_task = std::make_unique<
- webrtc_repeating_task_impl::RepeatingTaskImpl<Closure>>(
- task_queue, first_delay, std::forward<Closure>(closure), clock);
- auto* repeating_task_ptr = repeating_task.get();
- task_queue->PostDelayedTask(std::move(repeating_task), first_delay.ms());
- return RepeatingTaskHandle(repeating_task_ptr);
- }
- // 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
- // not be running after Stop() returns unless Stop() is called from the
- // closure itself.
- void Stop();
- // Returns true if Start() or DelayedStart() was called most recently. Returns
- // false initially and if Stop() or PostStop() was called most recently.
- bool Running() const;
- private:
- explicit RepeatingTaskHandle(
- webrtc_repeating_task_impl::RepeatingTaskBase* repeating_task);
- // Owned by the task queue.
- webrtc_repeating_task_impl::RepeatingTaskBase* repeating_task_ = nullptr;
- };
- } // namespace webrtc
- #endif // RTC_BASE_TASK_UTILS_REPEATING_TASK_H_
|