Commit 6698301a authored by Shubhanshu Agrawal's avatar Shubhanshu Agrawal Committed by Facebook Github Bot 9

adding Promise::await

Summary:
This diff adds a static await method to Promise.
Also after this, folly::fibers::await is just a wrapper around Promise::await.
This also removes the friend relationship between Promise and await.

This would be helpful in making the folly::fibers::await templated by Baton changes easier to make.

Reviewed By: andriigrynenko

Differential Revision: D3314891

fbshipit-source-id: 361546c078caafd067734d2f474c617d7fb888b0
parent 75f97748
...@@ -546,25 +546,7 @@ template <typename F> ...@@ -546,25 +546,7 @@ template <typename F>
typename FirstArgOf<F>::type::value_type inline await(F&& func) { typename FirstArgOf<F>::type::value_type inline await(F&& func) {
typedef typename FirstArgOf<F>::type::value_type Result; typedef typename FirstArgOf<F>::type::value_type Result;
folly::Try<Result> result; return Promise<Result>::await(std::forward<F>(func));
std::exception_ptr funcException;
Baton baton;
baton.wait([&func, &result, &baton, &funcException]() mutable {
try {
func(Promise<Result>(result, baton));
} catch (...) {
// Save the exception, but still wait for baton to be posted by user code
// or promise destructor.
funcException = std::current_exception();
}
});
if (UNLIKELY(funcException != nullptr)) {
std::rethrow_exception(funcException);
}
return folly::moveFromTry(result);
} }
} }
} }
...@@ -88,5 +88,29 @@ template <class F> ...@@ -88,5 +88,29 @@ template <class F>
void Promise<T>::setWith(F&& func) { void Promise<T>::setWith(F&& func) {
setTry(makeTryWith(std::forward<F>(func))); setTry(makeTryWith(std::forward<F>(func)));
} }
template <class T>
template <class F>
typename Promise<T>::value_type Promise<T>::await(F&& func) {
folly::Try<value_type> result;
std::exception_ptr funcException;
Baton baton;
baton.wait([&func, &result, &baton, &funcException]() mutable {
try {
func(Promise<value_type>(result, baton));
} catch (...) {
// Save the exception, but still wait for baton to be posted by user code
// or promise destructor.
funcException = std::current_exception();
}
});
if (UNLIKELY(funcException != nullptr)) {
std::rethrow_exception(funcException);
}
return folly::moveFromTry(result);
}
} }
} }
...@@ -23,9 +23,6 @@ namespace fibers { ...@@ -23,9 +23,6 @@ namespace fibers {
class Baton; class Baton;
template <typename F>
typename FirstArgOf<F>::type::value_type inline await(F&& func);
template <typename T> template <typename T>
class Promise { class Promise {
public: public:
...@@ -72,10 +69,17 @@ class Promise { ...@@ -72,10 +69,17 @@ class Promise {
*/ */
void setException(folly::exception_wrapper); void setException(folly::exception_wrapper);
private: /**
template <typename F> * Blocks task execution until given promise is fulfilled.
friend typename FirstArgOf<F>::type::value_type await(F&&); *
* Calls function passing in a Promise<T>, which has to be fulfilled.
*
* @return data which was used to fulfill the promise.
*/
template <class F>
static value_type await(F&& func);
private:
Promise(folly::Try<T>& value, Baton& baton); Promise(folly::Try<T>& value, Baton& baton);
folly::Try<T>* value_; folly::Try<T>* value_;
Baton* baton_; Baton* baton_;
......
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