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) {
}
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(
......@@ -312,9 +313,11 @@ void FiberManager::addTaskRemote(F&& func) {
}
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 {
......@@ -395,7 +398,8 @@ struct FiberManager::AddTaskFinallyHelper {
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,
......
......@@ -190,8 +190,8 @@ class FiberManager : public ::folly::Executor {
* 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.
*
......@@ -209,8 +209,8 @@ class FiberManager : public ::folly::Executor {
* 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 {
......
......@@ -1406,6 +1406,29 @@ TEST(FiberManager, remoteFutureTest) {
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;
......
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