Summary:We are jumping through some ugly hoops in the implementation of
fibers to allow for non-copyable functors/lambdas. We can get rid of
those by using folly::Function instead of std::function to store
functions in folly::fibers::Fiber.
This involves one observable interface change: the virtual function
folly::fibers::InlineFunctionRunner::run must take a
folly::Function<void()> argument instead of a std::function<void()>.
Reviewed By: andriigrynenko
Differential Revision:
D3102711
fb-gh-sync-id:
56705b972dc24cc0da551109ed44732b97cb6e13
fbshipit-source-id:
56705b972dc24cc0da551109ed44732b97cb6e13
#include <boost/version.hpp>
#include <folly/AtomicLinkedList.h>
#include <folly/CPortability.h>
+#include <folly/Function.h>
#include <folly/IntrusiveList.h>
#include <folly/experimental/fibers/BoostContextCompatibility.h>
#include <folly/io/async/Request.h>
FContext fcontext_; /**< current task execution context */
intptr_t data_; /**< Used to keep some data with the Fiber */
std::shared_ptr<RequestContext> rcontext_; /**< current RequestContext */
- std::function<void()> func_; /**< task function */
+ folly::Function<void()> func_; /**< task function */
bool recordStackUsed_{false};
bool stackFilledWithMagic_{false};
void* getUserBuffer();
- std::function<void()> resultFunc_;
- std::function<void()> finallyFunc_;
+ folly::Function<void()> resultFunc_;
+ folly::Function<void()> finallyFunc_;
class LocalData {
public:
template <typename F>
void FiberManager::addTaskRemote(F&& func) {
- // addTaskRemote indirectly requires wrapping the function in a
- // std::function, which must be copyable. As move-only lambdas may be
- // passed in we wrap it first in a move wrapper and then capture the wrapped
- // version.
- auto functionWrapper = [f = folly::makeMoveWrapper(
- std::forward<F>(func))]() mutable {
- return (*f)();
- };
auto task = [&]() {
auto currentFm = getFiberManagerUnsafe();
if (currentFm &&
currentFm->currentFiber_ &&
currentFm->localType_ == localType_) {
return folly::make_unique<RemoteTask>(
- std::move(functionWrapper), currentFm->currentFiber_->localData_);
+ std::forward<F>(func), currentFm->currentFiber_->localData_);
}
- return folly::make_unique<RemoteTask>(std::move(functionWrapper));
+ return folly::make_unique<RemoteTask>(std::forward<F>(func));
}();
auto insertHead =
[&]() { return remoteTaskQueue_.insertHead(task.release()); };
/**
* func must be executed inline and only once.
*/
- virtual void run(std::function<void()> func) = 0;
+ virtual void run(folly::Function<void()> func) = 0;
};
/**
constexpr Options() {}
};
- typedef std::function<void(std::exception_ptr, std::string)>
- ExceptionCallback;
+ using ExceptionCallback =
+ folly::Function<void(std::exception_ptr, std::string)>;
FiberManager(const FiberManager&) = delete;
FiberManager& operator=(const FiberManager&) = delete;
-> folly::Future<typename std::result_of<F()>::type>;
// Executor interface calls addTaskRemote
- void add(std::function<void()> f) {
+ void add(folly::Func f) override {
addTaskRemote(std::move(f));
}
func(std::forward<F>(f)),
localData(folly::make_unique<Fiber::LocalData>(localData_)),
rcontext(RequestContext::saveContext()) {}
- std::function<void()> func;
+ folly::Function<void()> func;
std::unique_ptr<Fiber::LocalData> localData;
std::shared_ptr<RequestContext> rcontext;
AtomicLinkedListHook<RemoteTask> nextRemoteTask;
/**
* Function passed to the await call.
*/
- std::function<void(Fiber&)> awaitFunc_;
+ folly::Function<void(Fiber&)> awaitFunc_;
/**
* Function passed to the runInMainContext call.
*/
- std::function<void()> immediateFunc_;
+ folly::Function<void()> immediateFunc_;
/**
* Preempt runner.