(Wangle) Don't add an extra value() call for makeFuture(Try)
[folly.git] / folly / futures / Future-inl.h
1 /*
2  * Copyright 2014 Facebook, Inc.
3  *
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
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #pragma once
18
19 #include <chrono>
20 #include <thread>
21
22 #include <folly/Baton.h>
23 #include <folly/futures/detail/Core.h>
24 #include <folly/futures/Timekeeper.h>
25
26 namespace folly {
27
28 class Timekeeper;
29
30 namespace detail {
31   Timekeeper* getTimekeeperSingleton();
32 }
33
34 template <typename T>
35 struct isFuture {
36   static const bool value = false;
37 };
38
39 template <typename T>
40 struct isFuture<Future<T> > {
41   static const bool value = true;
42 };
43
44 template <class T>
45 Future<T>::Future(Future<T>&& other) noexcept : core_(nullptr) {
46   *this = std::move(other);
47 }
48
49 template <class T>
50 Future<T>& Future<T>::operator=(Future<T>&& other) {
51   std::swap(core_, other.core_);
52   return *this;
53 }
54
55 template <class T>
56 Future<T>::~Future() {
57   detach();
58 }
59
60 template <class T>
61 void Future<T>::detach() {
62   if (core_) {
63     core_->detachFuture();
64     core_ = nullptr;
65   }
66 }
67
68 template <class T>
69 void Future<T>::throwIfInvalid() const {
70   if (!core_)
71     throw NoState();
72 }
73
74 template <class T>
75 template <class F>
76 void Future<T>::setCallback_(F&& func) {
77   throwIfInvalid();
78   core_->setCallback(std::move(func));
79 }
80
81 // Variant: f.then([](Try<T>&& t){ return t.value(); });
82 template <class T>
83 template <class F>
84 typename std::enable_if<
85   !isFuture<typename std::result_of<F(Try<T>&&)>::type>::value,
86   Future<typename std::result_of<F(Try<T>&&)>::type> >::type
87 Future<T>::then(F&& func) {
88   typedef typename std::result_of<F(Try<T>&&)>::type B;
89
90   throwIfInvalid();
91
92   // wrap these so we can move them into the lambda
93   folly::MoveWrapper<Promise<B>> p;
94   folly::MoveWrapper<F> funcm(std::forward<F>(func));
95
96   // grab the Future now before we lose our handle on the Promise
97   auto f = p->getFuture();
98
99   /* This is a bit tricky.
100
101      We can't just close over *this in case this Future gets moved. So we
102      make a new dummy Future. We could figure out something more
103      sophisticated that avoids making a new Future object when it can, as an
104      optimization. But this is correct.
105
106      core_ can't be moved, it is explicitly disallowed (as is copying). But
107      if there's ever a reason to allow it, this is one place that makes that
108      assumption and would need to be fixed. We use a standard shared pointer
109      for core_ (by copying it in), which means in essence obj holds a shared
110      pointer to itself.  But this shouldn't leak because Promise will not
111      outlive the continuation, because Promise will setException() with a
112      broken Promise if it is destructed before completed. We could use a
113      weak pointer but it would have to be converted to a shared pointer when
114      func is executed (because the Future returned by func may possibly
115      persist beyond the callback, if it gets moved), and so it is an
116      optimization to just make it shared from the get-go.
117
118      We have to move in the Promise and func using the MoveWrapper
119      hack. (func could be copied but it's a big drag on perf).
120
121      Two subtle but important points about this design. detail::Core has no
122      back pointers to Future or Promise, so if Future or Promise get moved
123      (and they will be moved in performant code) we don't have to do
124      anything fancy. And because we store the continuation in the
125      detail::Core, not in the Future, we can execute the continuation even
126      after the Future has gone out of scope. This is an intentional design
127      decision. It is likely we will want to be able to cancel a continuation
128      in some circumstances, but I think it should be explicit not implicit
129      in the destruction of the Future used to create it.
130      */
131   setCallback_(
132     [p, funcm](Try<T>&& t) mutable {
133       p->fulfil([&]() {
134         return (*funcm)(std::move(t));
135       });
136     });
137
138   return f;
139 }
140
141 // Variant: f.then([](T&& t){ return t; });
142 template <class T>
143 template <class F>
144 typename std::enable_if<
145   !std::is_same<T, void>::value &&
146   !isFuture<typename std::result_of<
147     F(typename detail::AliasIfVoid<T>::type&&)>::type>::value,
148   Future<typename std::result_of<
149     F(typename detail::AliasIfVoid<T>::type&&)>::type> >::type
150 Future<T>::then(F&& func) {
151   typedef typename std::result_of<F(T&&)>::type B;
152
153   throwIfInvalid();
154
155   folly::MoveWrapper<Promise<B>> p;
156   folly::MoveWrapper<F> funcm(std::forward<F>(func));
157   auto f = p->getFuture();
158
159   setCallback_(
160     [p, funcm](Try<T>&& t) mutable {
161       if (t.hasException()) {
162         p->setException(std::move(t.exception()));
163       } else {
164         p->fulfil([&]() {
165           return (*funcm)(std::move(t.value()));
166         });
167       }
168     });
169
170   return f;
171 }
172
173 // Variant: f.then([](){ return; });
174 template <class T>
175 template <class F>
176 typename std::enable_if<
177   std::is_same<T, void>::value &&
178   !isFuture<typename std::result_of<F()>::type>::value,
179   Future<typename std::result_of<F()>::type> >::type
180 Future<T>::then(F&& func) {
181   typedef typename std::result_of<F()>::type B;
182
183   throwIfInvalid();
184
185   folly::MoveWrapper<Promise<B>> p;
186   folly::MoveWrapper<F> funcm(std::forward<F>(func));
187   auto f = p->getFuture();
188
189   setCallback_(
190     [p, funcm](Try<T>&& t) mutable {
191       if (t.hasException()) {
192         p->setException(std::move(t.exception()));
193       } else {
194         p->fulfil([&]() {
195           return (*funcm)();
196         });
197       }
198     });
199
200   return f;
201 }
202
203 // Variant: f.then([](Try<T>&& t){ return makeFuture<T>(t.value()); });
204 template <class T>
205 template <class F>
206 typename std::enable_if<
207   isFuture<typename std::result_of<F(Try<T>&&)>::type>::value,
208   Future<typename std::result_of<F(Try<T>&&)>::type::value_type> >::type
209 Future<T>::then(F&& func) {
210   typedef typename std::result_of<F(Try<T>&&)>::type::value_type B;
211
212   throwIfInvalid();
213
214   // wrap these so we can move them into the lambda
215   folly::MoveWrapper<Promise<B>> p;
216   folly::MoveWrapper<F> funcm(std::forward<F>(func));
217
218   // grab the Future now before we lose our handle on the Promise
219   auto f = p->getFuture();
220
221   setCallback_(
222     [p, funcm](Try<T>&& t) mutable {
223       try {
224         auto f2 = (*funcm)(std::move(t));
225         // that didn't throw, now we can steal p
226         f2.setCallback_([p](Try<B>&& b) mutable {
227           p->fulfilTry(std::move(b));
228         });
229       } catch (const std::exception& e) {
230         p->setException(exception_wrapper(std::current_exception(), e));
231       } catch (...) {
232         p->setException(exception_wrapper(std::current_exception()));
233       }
234     });
235
236   return f;
237 }
238
239 // Variant: f.then([](T&& t){ return makeFuture<T>(t); });
240 template <class T>
241 template <class F>
242 typename std::enable_if<
243   !std::is_same<T, void>::value &&
244   isFuture<typename std::result_of<
245     F(typename detail::AliasIfVoid<T>::type&&)>::type>::value,
246   Future<typename std::result_of<
247     F(typename detail::AliasIfVoid<T>::type&&)>::type::value_type> >::type
248 Future<T>::then(F&& func) {
249   typedef typename std::result_of<F(T&&)>::type::value_type B;
250
251   throwIfInvalid();
252
253   folly::MoveWrapper<Promise<B>> p;
254   folly::MoveWrapper<F> funcm(std::forward<F>(func));
255   auto f = p->getFuture();
256
257   setCallback_(
258     [p, funcm](Try<T>&& t) mutable {
259       if (t.hasException()) {
260         p->setException(std::move(t.exception()));
261       } else {
262         try {
263           auto f2 = (*funcm)(std::move(t.value()));
264           f2.setCallback_([p](Try<B>&& b) mutable {
265             p->fulfilTry(std::move(b));
266           });
267         } catch (const std::exception& e) {
268           p->setException(exception_wrapper(std::current_exception(), e));
269         } catch (...) {
270           p->setException(exception_wrapper(std::current_exception()));
271         }
272       }
273     });
274
275   return f;
276 }
277
278 // Variant: f.then([](){ return makeFuture(); });
279 template <class T>
280 template <class F>
281 typename std::enable_if<
282   std::is_same<T, void>::value &&
283   isFuture<typename std::result_of<F()>::type>::value,
284   Future<typename std::result_of<F()>::type::value_type> >::type
285 Future<T>::then(F&& func) {
286   typedef typename std::result_of<F()>::type::value_type B;
287
288   throwIfInvalid();
289
290   folly::MoveWrapper<Promise<B>> p;
291   folly::MoveWrapper<F> funcm(std::forward<F>(func));
292
293   auto f = p->getFuture();
294
295   setCallback_(
296     [p, funcm](Try<T>&& t) mutable {
297       if (t.hasException()) {
298         p->setException(t.exception());
299       } else {
300         try {
301           auto f2 = (*funcm)();
302           f2.setCallback_([p](Try<B>&& b) mutable {
303             p->fulfilTry(std::move(b));
304           });
305         } catch (const std::exception& e) {
306           p->setException(exception_wrapper(std::current_exception(), e));
307         } catch (...) {
308           p->setException(exception_wrapper(std::current_exception()));
309         }
310       }
311     });
312
313   return f;
314 }
315
316 template <class T>
317 Future<void> Future<T>::then() {
318   return then([] (Try<T>&& t) {});
319 }
320
321 // onError where the callback returns T
322 template <class T>
323 template <class F>
324 typename std::enable_if<
325   !detail::Extract<F>::ReturnsFuture::value,
326   Future<T>>::type
327 Future<T>::onError(F&& func) {
328   typedef typename detail::Extract<F>::FirstArg Exn;
329   static_assert(
330       std::is_same<typename detail::Extract<F>::RawReturn, T>::value,
331       "Return type of onError callback must be T or Future<T>");
332
333   Promise<T> p;
334   auto f = p.getFuture();
335   auto pm = folly::makeMoveWrapper(std::move(p));
336   auto funcm = folly::makeMoveWrapper(std::move(func));
337   setCallback_([pm, funcm](Try<T>&& t) mutable {
338     if (!t.template withException<Exn>([&] (Exn& e) {
339           pm->fulfil([&]{
340             return (*funcm)(e);
341           });
342         })) {
343       pm->fulfilTry(std::move(t));
344     }
345   });
346
347   return f;
348 }
349
350 // onError where the callback returns Future<T>
351 template <class T>
352 template <class F>
353 typename std::enable_if<
354   detail::Extract<F>::ReturnsFuture::value,
355   Future<T>>::type
356 Future<T>::onError(F&& func) {
357   static_assert(
358       std::is_same<typename detail::Extract<F>::Return, Future<T>>::value,
359       "Return type of onError callback must be T or Future<T>");
360   typedef typename detail::Extract<F>::FirstArg Exn;
361
362   Promise<T> p;
363   auto f = p.getFuture();
364   auto pm = folly::makeMoveWrapper(std::move(p));
365   auto funcm = folly::makeMoveWrapper(std::move(func));
366   setCallback_([pm, funcm](Try<T>&& t) mutable {
367     if (!t.template withException<Exn>([&] (Exn& e) {
368           try {
369             auto f2 = (*funcm)(e);
370             f2.setCallback_([pm](Try<T>&& t2) mutable {
371               pm->fulfilTry(std::move(t2));
372             });
373           } catch (const std::exception& e2) {
374             pm->setException(exception_wrapper(std::current_exception(), e2));
375           } catch (...) {
376             pm->setException(exception_wrapper(std::current_exception()));
377           }
378         })) {
379       pm->fulfilTry(std::move(t));
380     }
381   });
382
383   return f;
384 }
385
386 template <class T>
387 typename std::add_lvalue_reference<T>::type Future<T>::value() {
388   throwIfInvalid();
389
390   return core_->getTry().value();
391 }
392
393 template <class T>
394 typename std::add_lvalue_reference<const T>::type Future<T>::value() const {
395   throwIfInvalid();
396
397   return core_->getTry().value();
398 }
399
400 template <class T>
401 Try<T>& Future<T>::getTry() {
402   throwIfInvalid();
403
404   return core_->getTry();
405 }
406
407 template <class T>
408 template <typename Executor>
409 inline Future<T> Future<T>::via(Executor* executor) && {
410   throwIfInvalid();
411
412   this->deactivate();
413   core_->setExecutor(executor);
414
415   return std::move(*this);
416 }
417
418 template <class T>
419 template <typename Executor>
420 inline Future<T> Future<T>::via(Executor* executor) & {
421   throwIfInvalid();
422
423   MoveWrapper<Promise<T>> p;
424   auto f = p->getFuture();
425   then([p](Try<T>&& t) mutable { p->fulfilTry(std::move(t)); });
426   return std::move(f).via(executor);
427 }
428
429 template <class T>
430 bool Future<T>::isReady() const {
431   throwIfInvalid();
432   return core_->ready();
433 }
434
435 template <class T>
436 void Future<T>::raise(exception_wrapper exception) {
437   core_->raise(std::move(exception));
438 }
439
440 // makeFuture
441
442 template <class T>
443 Future<typename std::decay<T>::type> makeFuture(T&& t) {
444   Promise<typename std::decay<T>::type> p;
445   p.setValue(std::forward<T>(t));
446   return p.getFuture();
447 }
448
449 inline // for multiple translation units
450 Future<void> makeFuture() {
451   Promise<void> p;
452   p.setValue();
453   return p.getFuture();
454 }
455
456 template <class F>
457 auto makeFutureTry(
458     F&& func,
459     typename std::enable_if<!std::is_reference<F>::value, bool>::type sdf)
460     -> Future<decltype(func())> {
461   Promise<decltype(func())> p;
462   p.fulfil(
463     [&func]() {
464       return (func)();
465     });
466   return p.getFuture();
467 }
468
469 template <class F>
470 auto makeFutureTry(F const& func) -> Future<decltype(func())> {
471   F copy = func;
472   return makeFutureTry(std::move(copy));
473 }
474
475 template <class T>
476 Future<T> makeFuture(std::exception_ptr const& e) {
477   Promise<T> p;
478   p.setException(e);
479   return p.getFuture();
480 }
481
482 template <class T>
483 Future<T> makeFuture(exception_wrapper ew) {
484   Promise<T> p;
485   p.setException(std::move(ew));
486   return p.getFuture();
487 }
488
489 template <class T, class E>
490 typename std::enable_if<std::is_base_of<std::exception, E>::value,
491                         Future<T>>::type
492 makeFuture(E const& e) {
493   Promise<T> p;
494   p.setException(make_exception_wrapper<E>(e));
495   return p.getFuture();
496 }
497
498 template <class T>
499 Future<T> makeFuture(Try<T>&& t) {
500   Promise<typename std::decay<T>::type> p;
501   p.fulfilTry(std::move(t));
502   return p.getFuture();
503 }
504
505 template <>
506 inline Future<void> makeFuture(Try<void>&& t) {
507   if (t.hasException()) {
508     return makeFuture<void>(std::move(t.exception()));
509   } else {
510     return makeFuture();
511   }
512 }
513
514 // via
515 template <typename Executor>
516 Future<void> via(Executor* executor) {
517   return makeFuture().via(executor);
518 }
519
520 // when (variadic)
521
522 template <typename... Fs>
523 typename detail::VariadicContext<
524   typename std::decay<Fs>::type::value_type...>::type
525 whenAll(Fs&&... fs)
526 {
527   auto ctx =
528     new detail::VariadicContext<typename std::decay<Fs>::type::value_type...>();
529   ctx->total = sizeof...(fs);
530   auto f_saved = ctx->p.getFuture();
531   detail::whenAllVariadicHelper(ctx,
532     std::forward<typename std::decay<Fs>::type>(fs)...);
533   return f_saved;
534 }
535
536 // when (iterator)
537
538 template <class InputIterator>
539 Future<
540   std::vector<
541   Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
542 whenAll(InputIterator first, InputIterator last)
543 {
544   typedef
545     typename std::iterator_traits<InputIterator>::value_type::value_type T;
546
547   if (first >= last) {
548     return makeFuture(std::vector<Try<T>>());
549   }
550   size_t n = std::distance(first, last);
551
552   auto ctx = new detail::WhenAllContext<T>();
553
554   ctx->results.resize(n);
555
556   auto f_saved = ctx->p.getFuture();
557
558   for (size_t i = 0; first != last; ++first, ++i) {
559      assert(i < n);
560      auto& f = *first;
561      f.setCallback_([ctx, i, n](Try<T>&& t) {
562          ctx->results[i] = std::move(t);
563          if (++ctx->count == n) {
564            ctx->p.setValue(std::move(ctx->results));
565            delete ctx;
566          }
567        });
568   }
569
570   return f_saved;
571 }
572
573 template <class InputIterator>
574 Future<
575   std::pair<size_t,
576             Try<
577               typename
578               std::iterator_traits<InputIterator>::value_type::value_type> > >
579 whenAny(InputIterator first, InputIterator last) {
580   typedef
581     typename std::iterator_traits<InputIterator>::value_type::value_type T;
582
583   auto ctx = new detail::WhenAnyContext<T>(std::distance(first, last));
584   auto f_saved = ctx->p.getFuture();
585
586   for (size_t i = 0; first != last; first++, i++) {
587     auto& f = *first;
588     f.setCallback_([i, ctx](Try<T>&& t) {
589       if (!ctx->done.exchange(true)) {
590         ctx->p.setValue(std::make_pair(i, std::move(t)));
591       }
592       ctx->decref();
593     });
594   }
595
596   return f_saved;
597 }
598
599 template <class InputIterator>
600 Future<std::vector<std::pair<size_t, Try<typename
601   std::iterator_traits<InputIterator>::value_type::value_type>>>>
602 whenN(InputIterator first, InputIterator last, size_t n) {
603   typedef typename
604     std::iterator_traits<InputIterator>::value_type::value_type T;
605   typedef std::vector<std::pair<size_t, Try<T>>> V;
606
607   struct ctx_t {
608     V v;
609     size_t completed;
610     Promise<V> p;
611   };
612   auto ctx = std::make_shared<ctx_t>();
613   ctx->completed = 0;
614
615   // for each completed Future, increase count and add to vector, until we
616   // have n completed futures at which point we fulfil our Promise with the
617   // vector
618   auto it = first;
619   size_t i = 0;
620   while (it != last) {
621     it->then([ctx, n, i](Try<T>&& t) {
622       auto& v = ctx->v;
623       auto c = ++ctx->completed;
624       if (c <= n) {
625         assert(ctx->v.size() < n);
626         v.push_back(std::make_pair(i, std::move(t)));
627         if (c == n) {
628           ctx->p.fulfilTry(Try<V>(std::move(v)));
629         }
630       }
631     });
632
633     it++;
634     i++;
635   }
636
637   if (i < n) {
638     ctx->p.setException(std::runtime_error("Not enough futures"));
639   }
640
641   return ctx->p.getFuture();
642 }
643
644 template <typename T>
645 Future<T>
646 waitWithSemaphore(Future<T>&& f) {
647   Baton<> baton;
648   auto done = f.then([&](Try<T> &&t) {
649     baton.post();
650     return std::move(t.value());
651   });
652   baton.wait();
653   while (!done.isReady()) {
654     // There's a race here between the return here and the actual finishing of
655     // the future. f is completed, but the setup may not have finished on done
656     // after the baton has posted.
657     std::this_thread::yield();
658   }
659   return done;
660 }
661
662 template<>
663 inline Future<void> waitWithSemaphore<void>(Future<void>&& f) {
664   Baton<> baton;
665   auto done = f.then([&](Try<void> &&t) {
666     baton.post();
667     t.value();
668   });
669   baton.wait();
670   while (!done.isReady()) {
671     // There's a race here between the return here and the actual finishing of
672     // the future. f is completed, but the setup may not have finished on done
673     // after the baton has posted.
674     std::this_thread::yield();
675   }
676   return done;
677 }
678
679 template <typename T, class Dur>
680 Future<T>
681 waitWithSemaphore(Future<T>&& f, Dur timeout) {
682   auto baton = std::make_shared<Baton<>>();
683   auto done = f.then([baton](Try<T> &&t) {
684     baton->post();
685     return std::move(t.value());
686   });
687   baton->timed_wait(std::chrono::system_clock::now() + timeout);
688   return done;
689 }
690
691 template <class Dur>
692 Future<void>
693 waitWithSemaphore(Future<void>&& f, Dur timeout) {
694   auto baton = std::make_shared<Baton<>>();
695   auto done = f.then([baton](Try<void> &&t) {
696     baton->post();
697     t.value();
698   });
699   baton->timed_wait(std::chrono::system_clock::now() + timeout);
700   return done;
701 }
702
703 namespace {
704   template <class T>
705   void getWaitHelper(Future<T>* f) {
706     // If we already have a value do the cheap thing
707     if (f->isReady()) {
708       return;
709     }
710
711     folly::Baton<> baton;
712     f->then([&](Try<T> const&) {
713       baton.post();
714     });
715     baton.wait();
716   }
717
718   template <class T>
719   Future<T> getWaitTimeoutHelper(Future<T>* f, Duration dur) {
720     // TODO make and use variadic whenAny #5877971
721     Promise<T> p;
722     auto token = std::make_shared<std::atomic<bool>>();
723     folly::Baton<> baton;
724
725     folly::detail::getTimekeeperSingleton()->after(dur)
726       .then([&,token](Try<void> const& t) {
727         if (token->exchange(true) == false) {
728           try {
729             t.value();
730             p.setException(TimedOut());
731           } catch (std::exception const& e) {
732             p.setException(exception_wrapper(std::current_exception(), e));
733           } catch (...) {
734             p.setException(exception_wrapper(std::current_exception()));
735           }
736           baton.post();
737         }
738       });
739
740     f->then([&, token](Try<T>&& t) {
741       if (token->exchange(true) == false) {
742         p.fulfilTry(std::move(t));
743         baton.post();
744       }
745     });
746
747     baton.wait();
748     return p.getFuture();
749   }
750 }
751
752 template <class T>
753 T Future<T>::get() {
754   getWaitHelper(this);
755
756   // Big assumption here: the then() call above, since it doesn't move out
757   // the value, leaves us with a value to return here. This would be a big
758   // no-no in user code, but I'm invoking internal developer privilege. This
759   // is slightly more efficient (save a move()) especially if there's an
760   // exception (save a throw).
761   return std::move(value());
762 }
763
764 template <>
765 inline void Future<void>::get() {
766   getWaitHelper(this);
767   value();
768 }
769
770 template <class T>
771 T Future<T>::get(Duration dur) {
772   return std::move(getWaitTimeoutHelper(this, dur).value());
773 }
774
775 template <>
776 inline void Future<void>::get(Duration dur) {
777   getWaitTimeoutHelper(this, dur).value();
778 }
779
780 template <class T>
781 T Future<T>::getVia(DrivableExecutor* e) {
782   while (!isReady()) {
783     e->drive();
784   }
785   return std::move(value());
786 }
787
788 template <>
789 inline void Future<void>::getVia(DrivableExecutor* e) {
790   while (!isReady()) {
791     e->drive();
792   }
793   value();
794 }
795
796 template <class T>
797 Future<T> Future<T>::within(Duration dur, Timekeeper* tk) {
798   return within(dur, TimedOut(), tk);
799 }
800
801 template <class T>
802 template <class E>
803 Future<T> Future<T>::within(Duration dur, E e, Timekeeper* tk) {
804
805   struct Context {
806     Context(E ex) : exception(std::move(ex)), promise(), token(false) {}
807     E exception;
808     Promise<T> promise;
809     std::atomic<bool> token;
810   };
811   auto ctx = std::make_shared<Context>(std::move(e));
812
813   if (!tk) {
814     tk = folly::detail::getTimekeeperSingleton();
815   }
816
817   tk->after(dur)
818     .then([ctx](Try<void> const& t) {
819       if (ctx->token.exchange(true) == false) {
820         try {
821           t.throwIfFailed();
822           ctx->promise.setException(std::move(ctx->exception));
823         } catch (std::exception const& e2) {
824           ctx->promise.setException(
825               exception_wrapper(std::current_exception(), e2));
826         } catch (...) {
827           ctx->promise.setException(
828               exception_wrapper(std::current_exception()));
829         }
830       }
831     });
832
833   this->then([ctx](Try<T>&& t) {
834     if (ctx->token.exchange(true) == false) {
835       ctx->promise.fulfilTry(std::move(t));
836     }
837   });
838
839   return ctx->promise.getFuture();
840 }
841
842 template <class T>
843 Future<T> Future<T>::delayed(Duration dur, Timekeeper* tk) {
844   return whenAll(*this, futures::sleep(dur, tk))
845     .then([](std::tuple<Try<T>, Try<void>> tup) {
846       Try<T>& t = std::get<0>(tup);
847       return makeFuture<T>(std::move(t));
848     });
849 }
850
851 template <class T>
852 Future<T> Future<T>::wait() {
853   Baton<> baton;
854   auto done = then([&](Try<T> t) {
855     baton.post();
856     return makeFuture(std::move(t));
857   });
858   baton.wait();
859   while (!done.isReady()) {
860     // There's a race here between the return here and the actual finishing of
861     // the future. f is completed, but the setup may not have finished on done
862     // after the baton has posted.
863     std::this_thread::yield();
864   }
865   return done;
866 }
867
868 template <class T>
869 Future<T> Future<T>::wait(Duration dur) {
870   auto baton = std::make_shared<Baton<>>();
871   auto done = then([baton](Try<T> t) {
872     baton->post();
873     return makeFuture(std::move(t));
874   });
875   baton->timed_wait(std::chrono::system_clock::now() + dur);
876   return done;
877 }
878
879 template <class T>
880 Future<T>& Future<T>::waitVia(DrivableExecutor* e) & {
881   while (!isReady()) {
882     e->drive();
883   }
884   return *this;
885 }
886
887 template <class T>
888 Future<T> Future<T>::waitVia(DrivableExecutor* e) && {
889   while (!isReady()) {
890     e->drive();
891   }
892   return std::move(*this);
893 }
894
895 }
896
897 // I haven't included a Future<T&> specialization because I don't forsee us
898 // using it, however it is not difficult to add when needed. Refer to
899 // Future<void> for guidance. std::future and boost::future code would also be
900 // instructive.