X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2Fexperimental%2FFunctionScheduler.cpp;h=3677e53346a98d3cf865c40f50b985626c7a63dd;hb=5086391b848c323f58920b349937b9f91f92a6be;hp=98bd9ed71e85c8d3b2b0bbbe30d82b3c4db49649;hpb=0dd7a9a6756769a9e2142a40cf351a35c20a413f;p=folly.git diff --git a/folly/experimental/FunctionScheduler.cpp b/folly/experimental/FunctionScheduler.cpp index 98bd9ed7..3677e533 100644 --- a/folly/experimental/FunctionScheduler.cpp +++ b/folly/experimental/FunctionScheduler.cpp @@ -1,5 +1,5 @@ /* - * 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. @@ -63,7 +63,7 @@ struct PoissonDistributionFunctor { struct UniformDistributionFunctor { std::default_random_engine generator; - std::uniform_int_distribution<> dist; + std::uniform_int_distribution dist; UniformDistributionFunctor(milliseconds minInterval, milliseconds maxInterval) : generator(Random::rand32()), @@ -232,6 +232,25 @@ bool FunctionScheduler::cancelFunction(StringPiece nameID) { return false; } +bool FunctionScheduler::cancelFunctionAndWait(StringPiece nameID) { + std::unique_lock 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& l, FunctionHeap::iterator it) { // This function should only be called with mutex_ already locked. @@ -259,6 +278,14 @@ void FunctionScheduler::cancelAllFunctions() { currentFunction_ = nullptr; } +void FunctionScheduler::cancelAllFunctionsAndWait() { + std::unique_lock l(mutex_); + if (currentFunction_) { + runningCondvar_.wait(l, [this]() { return currentFunction_ == nullptr; }); + } + functions_.clear(); +} + bool FunctionScheduler::resetFunctionTimer(StringPiece nameID) { std::unique_lock l(mutex_); if (currentFunction_ && currentFunction_->name == nameID) { @@ -291,8 +318,6 @@ bool FunctionScheduler::start() { return false; } - running_ = true; - VLOG(1) << "Starting FunctionScheduler with " << functions_.size() << " functions."; auto now = steady_clock::now(); @@ -307,6 +332,8 @@ bool FunctionScheduler::start() { std::make_heap(functions_.begin(), functions_.end(), fnCmp_); thread_ = std::thread([&] { this->run(); }); + running_ = true; + return true; } @@ -355,6 +382,7 @@ void FunctionScheduler::run() { 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. @@ -417,6 +445,7 @@ void FunctionScheduler::runOneFunction(std::unique_lock& lock, } if (currentFunction_->runOnce) { // Don't reschedule if the function only needed to run once. + currentFunction_ = nullptr; return; } // Clear currentFunction_