<commit_before>/*
 *  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 <type_traits>
#include <utility>

#include "absl/memory/memory.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 "rtc_base/sequenced_task_checker.h"
#include "rtc_base/thread_checker.h"

namespace webrtc {

class RepeatingTaskHandle;

namespace webrtc_repeating_task_impl {
class RepeatingTaskBase : public QueuedTask {
 public:
  RepeatingTaskBase(TaskQueueBase* task_queue, TimeDelta first_delay);
  ~RepeatingTaskBase() override;
  virtual TimeDelta RunClosure() = 0;

 private:
  friend class ::webrtc::RepeatingTaskHandle;

  bool Run() final;
  void Stop() RTC_RUN_ON(task_queue_);
  void PostStop();

  TaskQueueBase* const task_queue_;
  // 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)
      : RepeatingTaskBase(task_queue, first_delay),
        closure_(std::forward<Closure>(closure)) {
    static_assert(
        std::is_same<TimeDelta,
                     typename std::result_of<decltype (&Closure::operator())(
                         Closure)>::type>::value,
        "");
  }

  TimeDelta RunClosure() override { return closure_(); }

 private:
  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();
  ~RepeatingTaskHandle();
  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) {
    auto repeating_task = absl::make_unique<
        webrtc_repeating_task_impl::RepeatingTaskImpl<Closure>>(
        task_queue, TimeDelta::Zero(), std::forward<Closure>(closure));
    auto* repeating_task_ptr = repeating_task.get();
    task_queue->PostTask(std::move(repeating_task));
    return RepeatingTaskHandle(repeating_task_ptr);
  }
  template <class Closure>
  static RepeatingTaskHandle Start(Closure&& closure) {
    return Start(TaskQueueBase::Current(), std::forward<Closure>(closure));
  }

  // 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) {
    auto repeating_task = absl::make_unique<
        webrtc_repeating_task_impl::RepeatingTaskImpl<Closure>>(
        task_queue, first_delay, std::forward<Closure>(closure));
    auto* repeating_task_ptr = repeating_task.get();
    task_queue->PostDelayedTask(std::move(repeating_task), first_delay.ms());
    return RepeatingTaskHandle(repeating_task_ptr);
  }
  template <class Closure>
  static RepeatingTaskHandle DelayedStart(TimeDelta first_delay,
                                          Closure&& closure) {
    return DelayedStart(TaskQueueBase::Current(), first_delay,
                        std::forward<Closure>(closure));
  }

  // 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();

  // Stops future invocations of the repeating task closure. The closure might
  // still be running when PostStop() returns, but there will be no future
  // invocation.
  void PostStop();<commit_msg>Removes TaskQueueBase::Current call in repeating task.<commit_after>/*
 *  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 <type_traits>
#include <utility>

#include "absl/memory/memory.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 "rtc_base/sequenced_task_checker.h"
#include "rtc_base/thread_checker.h"

namespace webrtc {

class RepeatingTaskHandle;

namespace webrtc_repeating_task_impl {
class RepeatingTaskBase : public QueuedTask {
 public:
  RepeatingTaskBase(TaskQueueBase* task_queue, TimeDelta first_delay);
  ~RepeatingTaskBase() override;
  virtual TimeDelta RunClosure() = 0;

 private:
  friend class ::webrtc::RepeatingTaskHandle;

  bool Run() final;
  void Stop() RTC_RUN_ON(task_queue_);
  void PostStop();

  TaskQueueBase* const task_queue_;
  // 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)
      : RepeatingTaskBase(task_queue, first_delay),
        closure_(std::forward<Closure>(closure)) {
    static_assert(
        std::is_same<TimeDelta,
                     typename std::result_of<decltype (&Closure::operator())(
                         Closure)>::type>::value,
        "");
  }

  TimeDelta RunClosure() override { return closure_(); }

 private:
  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();
  ~RepeatingTaskHandle();
  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) {
    auto repeating_task = absl::make_unique<
        webrtc_repeating_task_impl::RepeatingTaskImpl<Closure>>(
        task_queue, TimeDelta::Zero(), std::forward<Closure>(closure));
    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) {
    auto repeating_task = absl::make_unique<
        webrtc_repeating_task_impl::RepeatingTaskImpl<Closure>>(
        task_queue, first_delay, std::forward<Closure>(closure));
    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();

  // Stops future invocations of the repeating task closure. The closure might
  // still be running when PostStop() returns, but there will be no future
  // invocation.
  void PostStop();
{'fraction_non_alphanumeric': 0.08172584102134005, 'fraction_numerical': 0.0009318796011555307, 'mean_word_length': 3.7277533039647577, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1769650', 'n_tokens_mistral': 3154, 'n_tokens_neox': 3009, 'n_words': 991}