Commit 10c76792 authored by Shubhanshu Agrawal's avatar Shubhanshu Agrawal Committed by Facebook Github Bot 4

templating folly::fibers::await by Baton

Summary:
This diff templates folly::fibers::await by Baton.
This would be helpful in passing in custom BatonType's, which is needed for D3007734

Depends on: D3314891

Reviewed By: andriigrynenko

Differential Revision: D3314925

fbshipit-source-id: 9052dc503b9509f16cd41b5e3ede0479a98067aa
parent 05cdf111
...@@ -545,8 +545,9 @@ FiberManager::FiberManager( ...@@ -545,8 +545,9 @@ FiberManager::FiberManager(
template <typename F> 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;
typedef typename FirstArgOf<F>::type::baton_type BatonT;
return Promise<Result>::await(std::forward<F>(func)); return Promise<Result, BatonT>::await(std::forward<F>(func));
} }
} }
} }
...@@ -18,46 +18,46 @@ ...@@ -18,46 +18,46 @@
namespace folly { namespace folly {
namespace fibers { namespace fibers {
template <class T> template <class T, class BatonT>
Promise<T>::Promise(folly::Try<T>& value, Baton& baton) Promise<T, BatonT>::Promise(folly::Try<T>& value, BatonT& baton)
: value_(&value), baton_(&baton) {} : value_(&value), baton_(&baton) {}
template <class T> template <class T, class BatonT>
Promise<T>::Promise(Promise&& other) noexcept Promise<T, BatonT>::Promise(Promise&& other) noexcept
: value_(other.value_), baton_(other.baton_) { : value_(other.value_), baton_(other.baton_) {
other.value_ = nullptr; other.value_ = nullptr;
other.baton_ = nullptr; other.baton_ = nullptr;
} }
template <class T> template <class T, class BatonT>
Promise<T>& Promise<T>::operator=(Promise&& other) { Promise<T, BatonT>& Promise<T, BatonT>::operator=(Promise&& other) {
std::swap(value_, other.value_); std::swap(value_, other.value_);
std::swap(baton_, other.baton_); std::swap(baton_, other.baton_);
return *this; return *this;
} }
template <class T> template <class T, class BatonT>
void Promise<T>::throwIfFulfilled() const { void Promise<T, BatonT>::throwIfFulfilled() const {
if (!value_) { if (!value_) {
throw std::logic_error("promise already fulfilled"); throw std::logic_error("promise already fulfilled");
} }
} }
template <class T> template <class T, class BatonT>
Promise<T>::~Promise() { Promise<T, BatonT>::~Promise() {
if (value_) { if (value_) {
setException(folly::make_exception_wrapper<std::logic_error>( setException(folly::make_exception_wrapper<std::logic_error>(
"promise not fulfilled")); "promise not fulfilled"));
} }
} }
template <class T> template <class T, class BatonT>
void Promise<T>::setException(folly::exception_wrapper e) { void Promise<T, BatonT>::setException(folly::exception_wrapper e) {
setTry(folly::Try<T>(e)); setTry(folly::Try<T>(e));
} }
template <class T> template <class T, class BatonT>
void Promise<T>::setTry(folly::Try<T>&& t) { void Promise<T, BatonT>::setTry(folly::Try<T>&& t) {
throwIfFulfilled(); throwIfFulfilled();
*value_ = std::move(t); *value_ = std::move(t);
...@@ -68,37 +68,37 @@ void Promise<T>::setTry(folly::Try<T>&& t) { ...@@ -68,37 +68,37 @@ void Promise<T>::setTry(folly::Try<T>&& t) {
baton_->post(); baton_->post();
} }
template <class T> template <class T, class BatonT>
template <class M> template <class M>
void Promise<T>::setValue(M&& v) { void Promise<T, BatonT>::setValue(M&& v) {
static_assert(!std::is_same<T, void>::value, "Use setValue() instead"); static_assert(!std::is_same<T, void>::value, "Use setValue() instead");
setTry(folly::Try<T>(std::forward<M>(v))); setTry(folly::Try<T>(std::forward<M>(v)));
} }
template <class T> template <class T, class BatonT>
void Promise<T>::setValue() { void Promise<T, BatonT>::setValue() {
static_assert(std::is_same<T, void>::value, "Use setValue(value) instead"); static_assert(std::is_same<T, void>::value, "Use setValue(value) instead");
setTry(folly::Try<void>()); setTry(folly::Try<void>());
} }
template <class T> template <class T, class BatonT>
template <class F> template <class F>
void Promise<T>::setWith(F&& func) { void Promise<T, BatonT>::setWith(F&& func) {
setTry(makeTryWith(std::forward<F>(func))); setTry(makeTryWith(std::forward<F>(func)));
} }
template <class T> template <class T, class BatonT>
template <class F> template <class F>
typename Promise<T>::value_type Promise<T>::await(F&& func) { typename Promise<T, BatonT>::value_type Promise<T, BatonT>::await(F&& func) {
folly::Try<value_type> result; folly::Try<value_type> result;
std::exception_ptr funcException; std::exception_ptr funcException;
Baton baton; BatonT baton;
baton.wait([&func, &result, &baton, &funcException]() mutable { baton.wait([&func, &result, &baton, &funcException]() mutable {
try { try {
func(Promise<value_type>(result, baton)); func(Promise<value_type, BatonT>(result, baton));
} catch (...) { } catch (...) {
// Save the exception, but still wait for baton to be posted by user code // Save the exception, but still wait for baton to be posted by user code
// or promise destructor. // or promise destructor.
......
...@@ -23,10 +23,11 @@ namespace fibers { ...@@ -23,10 +23,11 @@ namespace fibers {
class Baton; class Baton;
template <typename T> template <typename T, typename BatonT = Baton>
class Promise { class Promise {
public: public:
typedef T value_type; typedef T value_type;
typedef BatonT baton_type;
~Promise(); ~Promise();
...@@ -80,9 +81,9 @@ class Promise { ...@@ -80,9 +81,9 @@ class Promise {
static value_type await(F&& func); static value_type await(F&& func);
private: private:
Promise(folly::Try<T>& value, Baton& baton); Promise(folly::Try<T>& value, BatonT& baton);
folly::Try<T>* value_; folly::Try<T>* value_;
Baton* baton_; BatonT* baton_;
void throwIfFulfilled() const; void throwIfFulfilled() const;
......
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