/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <folly/Try.h> #include <folly/fibers/traits.h> #include <folly/functional/Invoke.h> namespace folly { namespace fibers { class Baton; template <typename T, typename BatonT = Baton> class Promise { public: typedef T value_type; typedef BatonT baton_type; ~Promise(); // not copyable Promise(const Promise&) = delete; Promise& operator=(const Promise&) = delete; // movable Promise(Promise&&) noexcept; Promise& operator=(Promise&&); /** Fulfill this promise (only for Promise<void>) */ void setValue(); /** Set the value (use perfect forwarding for both move and copy) */ template <class M> void setValue(M&& value); /** * Fulfill the promise with a given try * * @param t A Try with either a value or an error. */ void setTry(folly::Try<T>&& t); /** Fulfill this promise with the result of a function that takes no arguments and returns something implicitly convertible to T. Captures exceptions. e.g. p.setWith([] { do something that may throw; return a T; }); */ template <class F> void setWith(F&& func); /** Fulfill the Promise with an exception_wrapper, e.g. auto ew = folly::try_and_catch([]{ ... }); if (ew) { p.setException(std::move(ew)); } */ void setException(folly::exception_wrapper); /** * Blocks task execution until given promise is fulfilled. * * 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_async(F&& func); #if !defined(_MSC_VER) template <class F> FOLLY_ERASE static value_type await(F&& func) { return await_sync(static_cast<F&&>(func)); } #endif private: Promise(folly::Try<T>& value, BatonT& baton); folly::Try<T>* value_; BatonT* baton_; void throwIfFulfilled() const; template <class F> typename std::enable_if< std::is_convertible<invoke_result_t<F>, T>::value && !std::is_same<T, void>::value>::type fulfilHelper(F&& func); template <class F> typename std::enable_if< std::is_same<invoke_result_t<F>, void>::value && std::is_same<T, void>::value>::type fulfilHelper(F&& func); }; } // namespace fibers } // namespace folly #include <folly/fibers/Promise-inl.h>