runOnce));
}
-bool FunctionScheduler::cancelFunction(StringPiece nameID) {
- std::unique_lock<std::mutex> l(mutex_);
-
+bool FunctionScheduler::cancelFunctionWithLock(
+ std::unique_lock<std::mutex>& lock,
+ StringPiece nameID) {
+ CHECK_EQ(lock.owns_lock(), true);
if (currentFunction_ && currentFunction_->name == nameID) {
// This function is currently being run. Clear currentFunction_
// The running thread will see this and won't reschedule the function.
currentFunction_ = nullptr;
+ cancellingCurrentFunction_ = true;
+ return true;
+ }
+ return false;
+}
+
+bool FunctionScheduler::cancelFunction(StringPiece nameID) {
+ std::unique_lock<std::mutex> l(mutex_);
+
+ if (cancelFunctionWithLock(l, nameID)) {
return true;
}
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_;
- });
+ if (cancelFunctionWithLock(l, nameID)) {
+ runningCondvar_.wait(l, [this]() { return !cancellingCurrentFunction_; });
+ return true;
}
for (auto it = functions_.begin(); it != functions_.end(); ++it) {
}
}
-void FunctionScheduler::cancelAllFunctions() {
- std::unique_lock<std::mutex> l(mutex_);
+bool FunctionScheduler::cancelAllFunctionsWithLock(
+ std::unique_lock<std::mutex>& lock) {
+ CHECK_EQ(lock.owns_lock(), true);
functions_.clear();
+ if (currentFunction_) {
+ cancellingCurrentFunction_ = true;
+ }
currentFunction_ = nullptr;
+ return cancellingCurrentFunction_;
+}
+
+void FunctionScheduler::cancelAllFunctions() {
+ std::unique_lock<std::mutex> l(mutex_);
+ cancelAllFunctionsWithLock(l);
}
void FunctionScheduler::cancelAllFunctionsAndWait() {
std::unique_lock<std::mutex> l(mutex_);
- if (currentFunction_) {
- runningCondvar_.wait(l, [this]() { return currentFunction_ == nullptr; });
+ if (cancelAllFunctionsWithLock(l)) {
+ runningCondvar_.wait(l, [this]() { return !cancellingCurrentFunction_; });
}
- functions_.clear();
}
bool FunctionScheduler::resetFunctionTimer(StringPiece 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 (!currentFunction_) {
// The function was cancelled while we were running it.
// We shouldn't reschedule it;
+ cancellingCurrentFunction_ = false;
return;
}
if (currentFunction_->runOnce) {
// Don't reschedule if the function only needed to run once.
+ currentFunction_ = nullptr;
return;
}
// Clear currentFunction_