2 * Copyright 2015-present Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #include "folly/experimental/ThreadedRepeatingFunctionRunner.h"
18 #include <glog/logging.h>
23 ThreadedRepeatingFunctionRunner::ThreadedRepeatingFunctionRunner() {}
25 ThreadedRepeatingFunctionRunner::~ThreadedRepeatingFunctionRunner() {
26 stopAndWarn("ThreadedRepeatingFunctionRunner");
29 void ThreadedRepeatingFunctionRunner::stopAndWarn(
30 const std::string& class_of_destructor) {
33 << "ThreadedRepeatingFunctionRunner::stop() should already have been "
34 << "called, since the " << class_of_destructor << " destructor is now "
35 << "running. This is unsafe because it means that its threads "
36 << "may be accessing class state that was already destroyed "
37 << "(e.g. derived class members, or members that were declared after "
38 << "the " << class_of_destructor << ") .";
43 void ThreadedRepeatingFunctionRunner::stop() {
47 bool ThreadedRepeatingFunctionRunner::stopImpl() {
49 std::unique_lock<std::mutex> lock(stopMutex_);
51 return false; // Do nothing if stop() is called twice.
56 for (auto& t : threads_) {
62 void ThreadedRepeatingFunctionRunner::add(
64 std::chrono::milliseconds initialSleep) {
65 threads_.emplace_back(
66 &ThreadedRepeatingFunctionRunner::executeInLoop,
72 bool ThreadedRepeatingFunctionRunner::waitFor(
73 std::chrono::milliseconds duration) noexcept {
74 using clock = std::chrono::steady_clock;
75 const auto deadline = clock::now() + duration;
76 std::unique_lock<std::mutex> lock(stopMutex_);
78 lock, deadline, [&] { return stopping_ || clock::now() > deadline; });
82 void ThreadedRepeatingFunctionRunner::executeInLoop(
84 std::chrono::milliseconds initialSleep) noexcept {
85 auto duration = initialSleep;
86 while (waitFor(duration)) {