2 * Copyright 2014 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include <type_traits>
26 #include <folly/MoveWrapper.h>
27 #include <folly/wangle/futures/Promise.h>
28 #include <folly/wangle/futures/Try.h>
29 #include <folly/wangle/futures/WangleException.h>
30 #include <folly/wangle/futures/detail/Types.h>
32 namespace folly { namespace wangle {
34 template <class> struct Promise;
38 template <class> struct Core;
39 template <class...> struct VariadicContext;
43 typedef typename std::conditional<
44 std::is_same<T, void>::value,
51 struct IsFuture : std::integral_constant<bool, false> {
55 template <template <typename T> class Future, typename T>
56 struct IsFuture<Future<T>> : std::integral_constant<bool, true> {
60 template <typename...>
63 template <typename Arg, typename... Args>
64 struct ArgType<Arg, Args...> {
70 typedef void FirstArg;
74 struct Extract : Extract<decltype(&L::operator())> { };
76 template <typename Class, typename R, typename... Args>
77 struct Extract<R(Class::*)(Args...) const> {
78 typedef IsFuture<R> ReturnsFuture;
79 typedef Future<typename ReturnsFuture::Inner> Return;
80 typedef typename ReturnsFuture::Inner RawReturn;
81 typedef typename ArgType<Args...>::FirstArg FirstArg;
84 template <typename Class, typename R, typename... Args>
85 struct Extract<R(Class::*)(Args...)> {
86 typedef IsFuture<R> ReturnsFuture;
87 typedef Future<typename ReturnsFuture::Inner> Return;
88 typedef typename ReturnsFuture::Inner RawReturn;
89 typedef typename ArgType<Args...>::FirstArg FirstArg;
97 template <typename T> struct isFuture;
99 /// This namespace is for utility functions that would usually be static
100 /// members of Future, except they don't make sense there because they don't
101 /// depend on the template type (rather, on the type of their arguments in
102 /// some cases). This is the least-bad naming scheme we could think of. Some
103 /// of the functions herein have really-likely-to-collide names, like "map"
106 /// Returns a Future that will complete after the specified duration. The
107 /// Duration typedef of a `std::chrono` duration type indicates the
108 /// resolution you can expect to be meaningful (milliseconds at the time of
109 /// writing). Normally you wouldn't need to specify a Timekeeper, we will
110 /// use the global wangle timekeeper (we run a thread whose job it is to
111 /// keep time for wangle timeouts) but we provide the option for power
114 /// The Timekeeper thread will be lazily created the first time it is
115 /// needed. If your program never uses any timeouts or other time-based
116 /// Futures you will pay no Timekeeper thread overhead.
117 Future<void> sleep(Duration, Timekeeper* = nullptr);
123 typedef T value_type;
126 Future(Future const&) = delete;
127 Future& operator=(Future const&) = delete;
130 Future(Future&&) noexcept;
131 Future& operator=(Future&&);
135 /** Return the reference to result. Should not be called if !isReady().
136 Will rethrow the exception if an exception has been
139 This function is not thread safe - the returned Future can only
140 be executed from the thread that the executor runs it in.
141 See below for a thread safe version
143 typename std::add_lvalue_reference<T>::type
145 typename std::add_lvalue_reference<const T>::type
148 /// Returns an inactive Future which will call back on the other side of
149 /// executor (when it is activated).
151 /// NB remember that Futures activate when they destruct. This is good,
152 /// it means that this will work:
154 /// f.via(e).then(a).then(b);
156 /// a and b will execute in the same context (the far side of e), because
157 /// the Future (temporary variable) created by via(e) does not call back
158 /// until it destructs, which is after then(a) and then(b) have been wired
161 /// But this is still racy:
163 /// f = f.via(e).then(a);
165 // The ref-qualifier allows for `this` to be moved out so we
166 // don't get access-after-free situations in chaining.
167 // https://akrzemi1.wordpress.com/2014/06/02/ref-qualifiers/
168 template <typename Executor>
169 Future<T> via(Executor* executor) &&;
171 /// This variant creates a new future, where the ref-qualifier && version
172 /// moves `this` out. This one is less efficient but avoids confusing users
173 /// when "return f.via(x);" fails.
174 template <typename Executor>
175 Future<T> via(Executor* executor) &;
177 /** True when the result (or exception) is ready. */
178 bool isReady() const;
180 /** A reference to the Try of the value */
183 /// Block until the future is fulfilled. Returns the value (moved out), or
184 /// throws the exception. The future must not already have a callback.
187 /// Block until the future is fulfilled, or until timed out. Returns the
188 /// value (moved out), or throws the exception (which might be a TimedOut
192 /** When this Future has completed, execute func which is a function that
193 takes a Try<T>&&. A Future for the return type of func is
196 Future<string> f2 = f1.then([](Try<T>&&) { return string("foo"); });
198 The Future given to the functor is ready, and the functor may call
199 value(), which may rethrow if this has captured an exception. If func
200 throws, the exception will be captured in the Future that is returned.
202 /* TODO n3428 and other async frameworks have something like then(scheduler,
203 Future), we might want to support a similar API which could be
204 implemented a little more efficiently than
205 f.via(executor).then(callback) */
207 typename std::enable_if<
208 !isFuture<typename std::result_of<F(Try<T>&&)>::type>::value,
209 Future<typename std::result_of<F(Try<T>&&)>::type> >::type
212 /// Variant where func takes a T directly, bypassing a try. Any exceptions
213 /// will be implicitly passed on to the resultant Future.
215 /// Future<int> f = makeFuture<int>(42).then([](int i) { return i+1; });
217 typename std::enable_if<
218 !std::is_same<T, void>::value &&
219 !isFuture<typename std::result_of<
220 F(typename detail::AliasIfVoid<T>::type&&)>::type>::value,
221 Future<typename std::result_of<
222 F(typename detail::AliasIfVoid<T>::type&&)>::type> >::type
225 /// Like the above variant, but for void futures. That is, func takes no
228 /// Future<int> f = makeFuture().then([] { return 42; });
230 typename std::enable_if<
231 std::is_same<T, void>::value &&
232 !isFuture<typename std::result_of<F()>::type>::value,
233 Future<typename std::result_of<F()>::type> >::type
236 /// Variant where func returns a Future<T> instead of a T. e.g.
238 /// Future<string> f2 = f1.then(
239 /// [](Try<T>&&) { return makeFuture<string>("foo"); });
241 typename std::enable_if<
242 isFuture<typename std::result_of<F(Try<T>&&)>::type>::value,
243 Future<typename std::result_of<F(Try<T>&&)>::type::value_type> >::type
246 /// Variant where func returns a Future<T2> and takes a T directly, bypassing
247 /// a Try. Any exceptions will be implicitly passed on to the resultant
248 /// Future. For example,
250 /// Future<int> f = makeFuture<int>(42).then(
251 /// [](int i) { return makeFuture<int>(i+1); });
253 typename std::enable_if<
254 !std::is_same<T, void>::value &&
255 isFuture<typename std::result_of<
256 F(typename detail::AliasIfVoid<T>::type&&)>::type>::value,
257 Future<typename std::result_of<
258 F(typename detail::AliasIfVoid<T>::type&&)>::type::value_type> >::type
261 /// Like the above variant, but for void futures. That is, func takes no
262 /// argument and returns a future.
264 /// Future<int> f = makeFuture().then(
265 /// [] { return makeFuture<int>(42); });
267 typename std::enable_if<
268 std::is_same<T, void>::value &&
269 isFuture<typename std::result_of<F()>::type>::value,
270 Future<typename std::result_of<F()>::type::value_type> >::type
273 /// Variant where func is an ordinary function (static method, method)
275 /// R doWork(Try<T>&&);
277 /// Future<R> f2 = f1.then(doWork);
282 /// static R doWork(Try<T>&&); }
284 /// Future<R> f2 = f1.then(&Worker::doWork);
285 template <class = T, class R = std::nullptr_t>
286 typename std::enable_if<!isFuture<R>::value, Future<R>>::type
287 inline then(R(*func)(Try<T>&&)) {
288 return then([func](Try<T>&& t) {
289 return (*func)(std::move(t));
293 /// Variant where func returns a Future<R> instead of a R. e.g.
296 /// Future<R> doWork(Try<T>&&); }
298 /// Future<R> f2 = f1.then(&Worker::doWork);
299 template <class = T, class R = std::nullptr_t>
300 typename std::enable_if<isFuture<R>::value, R>::type
301 inline then(R(*func)(Try<T>&&)) {
302 return then([func](Try<T>&& t) {
303 return (*func)(std::move(t));
307 /// Variant where func is an member function
310 /// R doWork(Try<T>&&); }
313 /// Future<R> f2 = f1.then(w, &Worker::doWork);
314 template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
315 typename std::enable_if<!isFuture<R>::value, Future<R>>::type
316 inline then(Caller *instance, R(Caller::*func)(Try<T>&&)) {
317 return then([instance, func](Try<T>&& t) {
318 return (instance->*func)(std::move(t));
322 // Same as above, but func takes void instead of Try<void>&&
323 template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
324 typename std::enable_if<
325 std::is_same<T, void>::value && !isFuture<R>::value, Future<R>>::type
326 inline then(Caller *instance, R(Caller::*func)()) {
327 return then([instance, func]() {
328 return (instance->*func)();
332 // Same as above, but func takes T&& instead of Try<T>&&
333 template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
334 typename std::enable_if<
335 !std::is_same<T, void>::value && !isFuture<R>::value, Future<R>>::type
338 R(Caller::*func)(typename detail::AliasIfVoid<T>::type&&)) {
339 return then([instance, func](T&& t) {
340 return (instance->*func)(std::move(t));
344 /// Variant where func returns a Future<R> instead of a R. e.g.
347 /// Future<R> doWork(Try<T>&&); }
350 /// Future<R> f2 = f1.then(w, &Worker::doWork);
351 template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
352 typename std::enable_if<isFuture<R>::value, R>::type
353 inline then(Caller *instance, R(Caller::*func)(Try<T>&&)) {
354 return then([instance, func](Try<T>&& t) {
355 return (instance->*func)(std::move(t));
359 // Same as above, but func takes void instead of Try<void>&&
360 template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
361 typename std::enable_if<
362 std::is_same<T, void>::value && isFuture<R>::value, R>::type
363 inline then(Caller *instance, R(Caller::*func)()) {
364 return then([instance, func]() {
365 return (instance->*func)();
369 // Same as above, but func takes T&& instead of Try<T>&&
370 template <class = T, class R = std::nullptr_t, class Caller = std::nullptr_t>
371 typename std::enable_if<
372 !std::is_same<T, void>::value && isFuture<R>::value, R>::type
375 R(Caller::*func)(typename detail::AliasIfVoid<T>::type&&)) {
376 return then([instance, func](T&& t) {
377 return (instance->*func)(std::move(t));
381 /// Convenience method for ignoring the value and creating a Future<void>.
382 /// Exceptions still propagate.
385 /// Set an error callback for this Future. The callback should take a single
386 /// argument of the type that you want to catch, and should return a value of
387 /// the same type as this Future, or a Future of that type (see overload
388 /// below). For instance,
392 /// throw std::runtime_error("oh no!");
395 /// .onError([] (std::runtime_error& e) {
396 /// LOG(INFO) << "std::runtime_error: " << e.what();
397 /// return -1; // or makeFuture<int>(-1)
400 typename std::enable_if<
401 !detail::Extract<F>::ReturnsFuture::value,
405 /// Overload of onError where the error callback returns a Future<T>
407 typename std::enable_if<
408 detail::Extract<F>::ReturnsFuture::value,
412 /// This is not the method you're looking for.
414 /// This needs to be public because it's used by make* and when*, and it's
415 /// not worth listing all those and their fancy template signatures as
416 /// friends. But it's not for public consumption.
418 void setCallback_(F&& func);
420 /// A Future's callback is executed when all three of these conditions have
421 /// become true: it has a value (set by the Promise), it has a callback (set
422 /// by then), and it is active (active by default).
424 /// Inactive Futures will activate upon destruction.
425 Future<T>& activate() & {
429 Future<T>& deactivate() & {
433 Future<T> activate() && {
435 return std::move(*this);
437 Future<T> deactivate() && {
439 return std::move(*this);
443 return core_->isActive();
447 void raise(E&& exception) {
448 raise(std::make_exception_ptr(std::forward<E>(exception)));
451 /// Raise an interrupt. If the promise holder has an interrupt
452 /// handler it will be called and potentially stop asynchronous work from
453 /// being done. This is advisory only - a promise holder may not set an
454 /// interrupt handler, or may do anything including ignore. But, if you know
455 /// your future supports this the most likely result is stopping or
456 /// preventing the asynchronous operation (if in time), and the promise
457 /// holder setting an exception on the future. (That may happen
458 /// asynchronously, of course.)
459 void raise(std::exception_ptr interrupt);
462 raise(FutureCancellation());
465 /// Delay the completion of this Future for at least this duration from
466 /// now. The optional Timekeeper is as with futures::sleep().
467 Future<T> delayed(Duration, Timekeeper* = nullptr);
470 typedef detail::Core<T>* corePtr;
472 // shared core state object
476 Future(corePtr obj) : core_(obj) {}
480 void throwIfInvalid() const;
482 friend class Promise<T>;
486 Make a completed Future by moving in a value. e.g.
489 auto f = makeFuture(std::move(foo));
493 auto f = makeFuture<string>("foo");
496 Future<typename std::decay<T>::type> makeFuture(T&& t);
498 /** Make a completed void Future. */
499 Future<void> makeFuture();
501 /** Make a completed Future by executing a function. If the function throws
502 we capture the exception, otherwise we capture the result. */
506 typename std::enable_if<
507 !std::is_reference<F>::value, bool>::type sdf = false)
508 -> Future<decltype(func())>;
513 -> Future<decltype(func())>;
515 /// Make a failed Future from an exception_ptr.
516 /// Because the Future's type cannot be inferred you have to specify it, e.g.
518 /// auto f = makeFuture<string>(std::current_exception());
520 Future<T> makeFuture(std::exception_ptr const& e);
522 /** Make a Future from an exception type E that can be passed to
523 std::make_exception_ptr(). */
524 template <class T, class E>
525 typename std::enable_if<std::is_base_of<std::exception, E>::value,
527 makeFuture(E const& e);
529 /** Make a Future out of a Try */
531 Future<T> makeFuture(Try<T>&& t);
534 * Return a new Future that will call back on the given Executor.
535 * This is just syntactic sugar for makeFuture().via(executor)
537 * @param executor the Executor to call back on
539 * @returns a void Future that will call back on the given executor
541 template <typename Executor>
542 Future<void> via(Executor* executor);
544 /** When all the input Futures complete, the returned Future will complete.
545 Errors do not cause early termination; this Future will always succeed
546 after all its Futures have finished (whether successfully or with an
549 The Futures are moved in, so your copies are invalid. If you need to
550 chain further from these Futures, use the variant with an output iterator.
552 XXX is this still true?
553 This function is thread-safe for Futures running on different threads.
555 The return type for Future<T> input is a Future<std::vector<Try<T>>>
557 template <class InputIterator>
558 Future<std::vector<Try<
559 typename std::iterator_traits<InputIterator>::value_type::value_type>>>
560 whenAll(InputIterator first, InputIterator last);
562 /// This version takes a varying number of Futures instead of an iterator.
563 /// The return type for (Future<T1>, Future<T2>, ...) input
564 /// is a Future<std::tuple<Try<T1>, Try<T2>, ...>>.
565 /// The Futures are moved in, so your copies are invalid.
566 template <typename... Fs>
567 typename detail::VariadicContext<
568 typename std::decay<Fs>::type::value_type...>::type
571 /** The result is a pair of the index of the first Future to complete and
572 the Try. If multiple Futures complete at the same time (or are already
573 complete when passed in), the "winner" is chosen non-deterministically.
575 This function is thread-safe for Futures running on different threads.
577 template <class InputIterator>
580 Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
581 whenAny(InputIterator first, InputIterator last);
583 /** when n Futures have completed, the Future completes with a vector of
584 the index and Try of those n Futures (the indices refer to the original
585 order, but the result vector will be in an arbitrary order)
589 template <class InputIterator>
590 Future<std::vector<std::pair<
592 Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>>
593 whenN(InputIterator first, InputIterator last, size_t n);
595 /** Wait for the given future to complete on a semaphore. Returns a completed
596 * future containing the result.
598 * NB if the promise for the future would be fulfilled in the same thread that
599 * you call this, it will deadlock.
602 Future<T> waitWithSemaphore(Future<T>&& f);
604 /** Wait for up to `timeout` for the given future to complete. Returns a future
605 * which may or may not be completed depending whether the given future
608 * Note: each call to this starts a (short-lived) thread and allocates memory.
610 template <typename T, class Dur>
611 Future<T> waitWithSemaphore(Future<T>&& f, Dur timeout);
615 #include <folly/wangle/futures/Future-inl.h>