Commit b31eb722 authored by Martin Martin's avatar Martin Martin Committed by Facebook Github Bot 2

Make addTask[Remote]Future() work for functions returning void.

Summary:
There's no Future<void>, you're supposed to use Future<Unit>
instead.  Unit has a "Lift" template to do the conversion.

Reviewed By: andriigrynenko

Differential Revision: D3241498

fb-gh-sync-id: db12d4f343685bc613b701e023c860c2c903ed4c
fbshipit-source-id: db12d4f343685bc613b701e023c860c2c903ed4c
parent 0a2b61fd
...@@ -281,9 +281,10 @@ void FiberManager::addTask(F&& func) { ...@@ -281,9 +281,10 @@ void FiberManager::addTask(F&& func) {
} }
template <typename F> template <typename F>
auto FiberManager::addTaskFuture(F&& func) auto FiberManager::addTaskFuture(F&& func) -> folly::Future<
-> folly::Future<typename std::result_of<F()>::type> { typename folly::Unit::Lift<typename std::result_of<F()>::type>::type> {
using T = typename std::result_of<F()>::type; using T =
typename folly::Unit::Lift<typename std::result_of<F()>::type>::type;
folly::Promise<T> p; folly::Promise<T> p;
auto f = p.getFuture(); auto f = p.getFuture();
addTaskFinally( addTaskFinally(
...@@ -312,9 +313,11 @@ void FiberManager::addTaskRemote(F&& func) { ...@@ -312,9 +313,11 @@ void FiberManager::addTaskRemote(F&& func) {
} }
template <typename F> template <typename F>
auto FiberManager::addTaskRemoteFuture(F&& func) auto FiberManager::addTaskRemoteFuture(F&& func) -> folly::Future<
-> folly::Future<typename std::result_of<F()>::type> { typename folly::Unit::Lift<typename std::result_of<F()>::type>::type> {
folly::Promise<typename std::result_of<F()>::type> p; folly::Promise<
typename folly::Unit::Lift<typename std::result_of<F()>::type>::type>
p;
auto f = p.getFuture(); auto f = p.getFuture();
addTaskRemote( addTaskRemote(
[ p = std::move(p), func = std::forward<F>(func), this ]() mutable { [ p = std::move(p), func = std::forward<F>(func), this ]() mutable {
...@@ -395,7 +398,8 @@ struct FiberManager::AddTaskFinallyHelper { ...@@ -395,7 +398,8 @@ struct FiberManager::AddTaskFinallyHelper {
template <typename F, typename G> template <typename F, typename G>
void FiberManager::addTaskFinally(F&& func, G&& finally) { 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( static_assert(
IsRvalueRefTry<typename FirstArgOf<G>::type>::value, IsRvalueRefTry<typename FirstArgOf<G>::type>::value,
......
...@@ -190,8 +190,8 @@ class FiberManager : public ::folly::Executor { ...@@ -190,8 +190,8 @@ class FiberManager : public ::folly::Executor {
* The object will be destroyed once task execution is complete. * The object will be destroyed once task execution is complete.
*/ */
template <typename F> template <typename F>
auto addTaskFuture(F&& func) auto addTaskFuture(F&& func) -> folly::Future<
-> folly::Future<typename std::result_of<F()>::type>; typename folly::Unit::Lift<typename std::result_of<F()>::type>::type>;
/** /**
* Add a new task to be executed. Safe to call from other threads. * Add a new task to be executed. Safe to call from other threads.
* *
...@@ -209,8 +209,8 @@ class FiberManager : public ::folly::Executor { ...@@ -209,8 +209,8 @@ class FiberManager : public ::folly::Executor {
* The object will be destroyed once task execution is complete. * The object will be destroyed once task execution is complete.
*/ */
template <typename F> template <typename F>
auto addTaskRemoteFuture(F&& func) auto addTaskRemoteFuture(F&& func) -> folly::Future<
-> folly::Future<typename std::result_of<F()>::type>; typename folly::Unit::Lift<typename std::result_of<F()>::type>::type>;
// Executor interface calls addTaskRemote // Executor interface calls addTaskRemote
void add(folly::Func f) override { void add(folly::Func f) override {
......
...@@ -1406,6 +1406,29 @@ TEST(FiberManager, remoteFutureTest) { ...@@ -1406,6 +1406,29 @@ TEST(FiberManager, remoteFutureTest) {
EXPECT_EQ(v2, testValue2); 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) { TEST(FiberManager, nestedFiberManagers) {
folly::EventBase outerEvb; folly::EventBase outerEvb;
folly::EventBase innerEvb; folly::EventBase innerEvb;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment