}
template <typename F>
-auto FiberManager::addTaskFuture(F&& func)
- -> folly::Future<typename std::result_of<F()>::type> {
- using T = typename std::result_of<F()>::type;
+auto FiberManager::addTaskFuture(F&& func) -> folly::Future<
+ typename folly::Unit::Lift<typename std::result_of<F()>::type>::type> {
+ using T =
+ typename folly::Unit::Lift<typename std::result_of<F()>::type>::type;
folly::Promise<T> p;
auto f = p.getFuture();
addTaskFinally(
}
template <typename F>
-auto FiberManager::addTaskRemoteFuture(F&& func)
- -> folly::Future<typename std::result_of<F()>::type> {
- folly::Promise<typename std::result_of<F()>::type> p;
+auto FiberManager::addTaskRemoteFuture(F&& func) -> folly::Future<
+ typename folly::Unit::Lift<typename std::result_of<F()>::type>::type> {
+ folly::Promise<
+ typename folly::Unit::Lift<typename std::result_of<F()>::type>::type>
+ p;
auto f = p.getFuture();
addTaskRemote(
[ p = std::move(p), func = std::forward<F>(func), this ]() mutable {
template <typename F, typename G>
void FiberManager::addTaskFinally(F&& func, G&& finally) {
- typedef typename std::result_of<F()>::type Result;
+ typedef typename folly::Unit::Lift<typename std::result_of<F()>::type>::type
+ Result;
static_assert(
IsRvalueRefTry<typename FirstArgOf<G>::type>::value,
* The object will be destroyed once task execution is complete.
*/
template <typename F>
- auto addTaskFuture(F&& func)
- -> folly::Future<typename std::result_of<F()>::type>;
+ auto addTaskFuture(F&& func) -> folly::Future<
+ typename folly::Unit::Lift<typename std::result_of<F()>::type>::type>;
/**
* Add a new task to be executed. Safe to call from other threads.
*
* The object will be destroyed once task execution is complete.
*/
template <typename F>
- auto addTaskRemoteFuture(F&& func)
- -> folly::Future<typename std::result_of<F()>::type>;
+ auto addTaskRemoteFuture(F&& func) -> folly::Future<
+ typename folly::Unit::Lift<typename std::result_of<F()>::type>::type>;
// Executor interface calls addTaskRemote
void add(folly::Func f) override {
EXPECT_EQ(v2, testValue2);
}
+// Test that a void function produes a Future<Unit>.
+TEST(FiberManager, remoteFutureVoidUnitTest) {
+ FiberManager fiberManager(folly::make_unique<SimpleLoopController>());
+ auto& loopController =
+ dynamic_cast<SimpleLoopController&>(fiberManager.loopController());
+
+ bool ranLocal = false;
+ folly::Future<folly::Unit> futureLocal =
+ fiberManager.addTaskFuture([&]() { ranLocal = true; });
+
+ bool ranRemote = false;
+ folly::Future<folly::Unit> futureRemote =
+ fiberManager.addTaskRemoteFuture([&]() { ranRemote = true; });
+
+ loopController.loop([&]() { loopController.stop(); });
+
+ futureLocal.wait();
+ ASSERT_TRUE(ranLocal);
+
+ futureRemote.wait();
+ ASSERT_TRUE(ranRemote);
+}
+
TEST(FiberManager, nestedFiberManagers) {
folly::EventBase outerEvb;
folly::EventBase innerEvb;