/*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
struct UniformDistributionFunctor {
std::default_random_engine generator;
- std::uniform_int_distribution<> dist;
+ std::uniform_int_distribution<milliseconds::rep> dist;
UniformDistributionFunctor(milliseconds minInterval, milliseconds maxInterval)
: generator(Random::rand32()),
return false;
}
+bool FunctionScheduler::cancelFunctionAndWait(StringPiece nameID) {
+ std::unique_lock<std::mutex> l(mutex_);
+
+ auto* currentFunction = currentFunction_;
+ if (currentFunction && currentFunction->name == nameID) {
+ runningCondvar_.wait(l, [currentFunction, this]() {
+ return currentFunction != currentFunction_;
+ });
+ }
+
+ for (auto it = functions_.begin(); it != functions_.end(); ++it) {
+ if (it->isValid() && it->name == nameID) {
+ cancelFunction(l, it);
+ return true;
+ }
+ }
+ return false;
+}
+
void FunctionScheduler::cancelFunction(const std::unique_lock<std::mutex>& l,
FunctionHeap::iterator it) {
// This function should only be called with mutex_ already locked.
currentFunction_ = nullptr;
}
+void FunctionScheduler::cancelAllFunctionsAndWait() {
+ std::unique_lock<std::mutex> l(mutex_);
+ if (currentFunction_) {
+ runningCondvar_.wait(l, [this]() { return currentFunction_ == nullptr; });
+ }
+ functions_.clear();
+}
+
bool FunctionScheduler::resetFunctionTimer(StringPiece nameID) {
std::unique_lock<std::mutex> l(mutex_);
if (currentFunction_ && currentFunction_->name == nameID) {
return false;
}
- running_ = true;
-
VLOG(1) << "Starting FunctionScheduler with " << functions_.size()
<< " functions.";
auto now = steady_clock::now();
std::make_heap(functions_.begin(), functions_.end(), fnCmp_);
thread_ = std::thread([&] { this->run(); });
+ running_ = true;
+
return true;
}
if (sleepTime < milliseconds::zero()) {
// We need to run this function now
runOneFunction(lock, now);
+ runningCondvar_.notify_all();
} else {
// Re-add the function to the heap, and wait until we actually
// need to run it.
}
if (currentFunction_->runOnce) {
// Don't reschedule if the function only needed to run once.
+ currentFunction_ = nullptr;
return;
}
// Clear currentFunction_