folly::fibers::Fiber: use folly::Function instead of std::function
authorSven Over <over@fb.com>
Wed, 6 Apr 2016 10:55:14 +0000 (03:55 -0700)
committerFacebook Github Bot 7 <facebook-github-bot-7-bot@fb.com>
Wed, 6 Apr 2016 11:05:49 +0000 (04:05 -0700)
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

folly/experimental/fibers/Fiber.h
folly/experimental/fibers/FiberManager-inl.h
folly/experimental/fibers/FiberManager.h

index 39a05fca23c29500f092d98834d3e290a8c832ae..a0e397f564f67db4c255eebe374e297d592da48b 100644 (file)
@@ -22,6 +22,7 @@
 #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>
@@ -119,7 +120,7 @@ class Fiber {
   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};
 
@@ -133,8 +134,8 @@ class Fiber {
 
   void* getUserBuffer();
 
-  std::function<void()> resultFunc_;
-  std::function<void()> finallyFunc_;
+  folly::Function<void()> resultFunc_;
+  folly::Function<void()> finallyFunc_;
 
   class LocalData {
    public:
index c7990c4444180c3f9db065aaeb5e908b2134a765..ea588a6802c538b60ac1ecf42dab934739841dc7 100644 (file)
@@ -299,23 +299,15 @@ auto FiberManager::addTaskFuture(F&& func)
 
 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()); };
index d9dfef2b9fa714e47c226a6e67f60291cff237f3..5c893e85692430077e3481ff4e2e7e8dfdb5a8dd 100644 (file)
@@ -61,7 +61,7 @@ class InlineFunctionRunner {
   /**
    * func must be executed inline and only once.
    */
-  virtual void run(std::function<void()> func) = 0;
+  virtual void run(folly::Function<void()> func) = 0;
 };
 
 /**
@@ -116,8 +116,8 @@ class FiberManager : public ::folly::Executor {
     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;
@@ -213,7 +213,7 @@ class FiberManager : public ::folly::Executor {
       -> 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));
   }
 
@@ -331,7 +331,7 @@ class FiberManager : public ::folly::Executor {
         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;
@@ -411,12 +411,12 @@ class FiberManager : public ::folly::Executor {
   /**
    * 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.