Commit e575bf39 authored by Andrii Grynenko's avatar Andrii Grynenko Committed by Facebook Github Bot

Fix addTaskRemoteFuture to work for functors returning Try<T>

Reviewed By: yfeldblum

Differential Revision: D17619144

fbshipit-source-id: 2d0c533fbf55b4ce1cfc787f53711fd1864a03c6
parent 09ce44b3
...@@ -219,10 +219,9 @@ void Try<void>::throwIfFailed() const { ...@@ -219,10 +219,9 @@ void Try<void>::throwIfFailed() const {
template <typename F> template <typename F>
typename std::enable_if< typename std::enable_if<
!std::is_same<invoke_result_t<F>, void>::value && !std::is_same<invoke_result_t<F>, void>::value,
!isTry<invoke_result_t<F>>::value,
Try<invoke_result_t<F>>>::type Try<invoke_result_t<F>>>::type
makeTryWith(F&& f) { makeTryWithNoUnwrap(F&& f) {
using ResultType = invoke_result_t<F>; using ResultType = invoke_result_t<F>;
try { try {
return Try<ResultType>(f()); return Try<ResultType>(f());
...@@ -236,7 +235,7 @@ makeTryWith(F&& f) { ...@@ -236,7 +235,7 @@ makeTryWith(F&& f) {
template <typename F> template <typename F>
typename std:: typename std::
enable_if<std::is_same<invoke_result_t<F>, void>::value, Try<void>>::type enable_if<std::is_same<invoke_result_t<F>, void>::value, Try<void>>::type
makeTryWith(F&& f) { makeTryWithNoUnwrap(F&& f) {
try { try {
f(); f();
return Try<void>(); return Try<void>();
...@@ -247,6 +246,13 @@ typename std:: ...@@ -247,6 +246,13 @@ typename std::
} }
} }
template <typename F>
typename std::
enable_if<!isTry<invoke_result_t<F>>::value, Try<invoke_result_t<F>>>::type
makeTryWith(F&& f) {
return makeTryWithNoUnwrap(std::forward<F>(f));
}
template <typename F> template <typename F>
typename std::enable_if<isTry<invoke_result_t<F>>::value, invoke_result_t<F>>:: typename std::enable_if<isTry<invoke_result_t<F>>::value, invoke_result_t<F>>::
type type
......
...@@ -598,10 +598,9 @@ struct isTry<Try<T>> : std::true_type {}; ...@@ -598,10 +598,9 @@ struct isTry<Try<T>> : std::true_type {};
*/ */
template <typename F> template <typename F>
typename std::enable_if< typename std::enable_if<
!std::is_same<invoke_result_t<F>, void>::value && !std::is_same<invoke_result_t<F>, void>::value,
!isTry<invoke_result_t<F>>::value,
Try<invoke_result_t<F>>>::type Try<invoke_result_t<F>>>::type
makeTryWith(F&& f); makeTryWithNoUnwrap(F&& f);
/* /*
* Specialization of makeTryWith for void return * Specialization of makeTryWith for void return
...@@ -613,6 +612,16 @@ makeTryWith(F&& f); ...@@ -613,6 +612,16 @@ makeTryWith(F&& f);
template <typename F> template <typename F>
typename std:: typename std::
enable_if<std::is_same<invoke_result_t<F>, void>::value, Try<void>>::type enable_if<std::is_same<invoke_result_t<F>, void>::value, Try<void>>::type
makeTryWithNoUnwrap(F&& f);
/*
* @param f a function to execute and capture the result of (value or exception)
*
* @returns Try holding the result of f
*/
template <typename F>
typename std::
enable_if<!isTry<invoke_result_t<F>>::value, Try<invoke_result_t<F>>>::type
makeTryWith(F&& f); makeTryWith(F&& f);
/* /*
......
...@@ -60,7 +60,7 @@ auto FiberManager::addTaskRemoteFuture(F&& func) ...@@ -60,7 +60,7 @@ auto FiberManager::addTaskRemoteFuture(F&& func)
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 {
auto t = folly::makeTryWith(std::forward<F>(func)); auto t = folly::makeTryWithNoUnwrap(std::forward<F>(func));
runInMainContext([&]() { p.setTry(std::move(t)); }); runInMainContext([&]() { p.setTry(std::move(t)); });
}); });
return f; return f;
......
...@@ -2514,3 +2514,15 @@ TEST(FiberManager, loopInUnwind) { ...@@ -2514,3 +2514,15 @@ TEST(FiberManager, loopInUnwind) {
} catch (...) { } catch (...) {
} }
} }
TEST(FiberManager, addTaskRemoteFutureTry) {
folly::EventBase evb;
auto& fm = getFiberManager(evb);
EXPECT_EQ(
42,
fm.addTaskRemoteFuture(
[&]() -> folly::Try<int> { return folly::Try<int>(42); })
.getVia(&evb)
.value());
}
...@@ -2148,7 +2148,7 @@ void waitViaImpl(Future<T>& f, DrivableExecutor* e) { ...@@ -2148,7 +2148,7 @@ void waitViaImpl(Future<T>& f, DrivableExecutor* e) {
if (f.isReady()) { if (f.isReady()) {
return; return;
} }
f = std::move(f).via(e).thenValue([](T&& t) { return std::move(t); }); f = std::move(f).via(e).thenTry([](Try<T>&& t) { return std::move(t); });
while (!f.isReady()) { while (!f.isReady()) {
e->drive(); e->drive();
} }
......
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