Revert "[futures] waitWithSemaphore -> Future<T>::wait()"
[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   if (t.hasException()) {
501     return makeFuture<T>(std::move(t.exception()));
502   } else {
503     return makeFuture<T>(std::move(t.value()));
504   }
505 }
506
507 template <>
508 inline Future<void> makeFuture(Try<void>&& t) {
509   if (t.hasException()) {
510     return makeFuture<void>(std::move(t.exception()));
511   } else {
512     return makeFuture();
513   }
514 }
515
516 // via
517 template <typename Executor>
518 Future<void> via(Executor* executor) {
519   return makeFuture().via(executor);
520 }
521
522 // when (variadic)
523
524 template <typename... Fs>
525 typename detail::VariadicContext<
526   typename std::decay<Fs>::type::value_type...>::type
527 whenAll(Fs&&... fs)
528 {
529   auto ctx =
530     new detail::VariadicContext<typename std::decay<Fs>::type::value_type...>();
531   ctx->total = sizeof...(fs);
532   auto f_saved = ctx->p.getFuture();
533   detail::whenAllVariadicHelper(ctx,
534     std::forward<typename std::decay<Fs>::type>(fs)...);
535   return f_saved;
536 }
537
538 // when (iterator)
539
540 template <class InputIterator>
541 Future<
542   std::vector<
543   Try<typename std::iterator_traits<InputIterator>::value_type::value_type>>>
544 whenAll(InputIterator first, InputIterator last)
545 {
546   typedef
547     typename std::iterator_traits<InputIterator>::value_type::value_type T;
548
549   if (first >= last) {
550     return makeFuture(std::vector<Try<T>>());
551   }
552   size_t n = std::distance(first, last);
553
554   auto ctx = new detail::WhenAllContext<T>();
555
556   ctx->results.resize(n);
557
558   auto f_saved = ctx->p.getFuture();
559
560   for (size_t i = 0; first != last; ++first, ++i) {
561      assert(i < n);
562      auto& f = *first;
563      f.setCallback_([ctx, i, n](Try<T>&& t) {
564          ctx->results[i] = std::move(t);
565          if (++ctx->count == n) {
566            ctx->p.setValue(std::move(ctx->results));
567            delete ctx;
568          }
569        });
570   }
571
572   return f_saved;
573 }
574
575 template <class InputIterator>
576 Future<
577   std::pair<size_t,
578             Try<
579               typename
580               std::iterator_traits<InputIterator>::value_type::value_type> > >
581 whenAny(InputIterator first, InputIterator last) {
582   typedef
583     typename std::iterator_traits<InputIterator>::value_type::value_type T;
584
585   auto ctx = new detail::WhenAnyContext<T>(std::distance(first, last));
586   auto f_saved = ctx->p.getFuture();
587
588   for (size_t i = 0; first != last; first++, i++) {
589     auto& f = *first;
590     f.setCallback_([i, ctx](Try<T>&& t) {
591       if (!ctx->done.exchange(true)) {
592         ctx->p.setValue(std::make_pair(i, std::move(t)));
593       }
594       ctx->decref();
595     });
596   }
597
598   return f_saved;
599 }
600
601 template <class InputIterator>
602 Future<std::vector<std::pair<size_t, Try<typename
603   std::iterator_traits<InputIterator>::value_type::value_type>>>>
604 whenN(InputIterator first, InputIterator last, size_t n) {
605   typedef typename
606     std::iterator_traits<InputIterator>::value_type::value_type T;
607   typedef std::vector<std::pair<size_t, Try<T>>> V;
608
609   struct ctx_t {
610     V v;
611     size_t completed;
612     Promise<V> p;
613   };
614   auto ctx = std::make_shared<ctx_t>();
615   ctx->completed = 0;
616
617   // for each completed Future, increase count and add to vector, until we
618   // have n completed futures at which point we fulfil our Promise with the
619   // vector
620   auto it = first;
621   size_t i = 0;
622   while (it != last) {
623     it->then([ctx, n, i](Try<T>&& t) {
624       auto& v = ctx->v;
625       auto c = ++ctx->completed;
626       if (c <= n) {
627         assert(ctx->v.size() < n);
628         v.push_back(std::make_pair(i, std::move(t)));
629         if (c == n) {
630           ctx->p.fulfilTry(Try<V>(std::move(v)));
631         }
632       }
633     });
634
635     it++;
636     i++;
637   }
638
639   if (i < n) {
640     ctx->p.setException(std::runtime_error("Not enough futures"));
641   }
642
643   return ctx->p.getFuture();
644 }
645
646 template <typename T>
647 Future<T>
648 waitWithSemaphore(Future<T>&& f) {
649   Baton<> baton;
650   auto done = f.then([&](Try<T> &&t) {
651     baton.post();
652     return std::move(t.value());
653   });
654   baton.wait();
655   while (!done.isReady()) {
656     // There's a race here between the return here and the actual finishing of
657     // the future. f is completed, but the setup may not have finished on done
658     // after the baton has posted.
659     std::this_thread::yield();
660   }
661   return done;
662 }
663
664 template<>
665 inline Future<void> waitWithSemaphore<void>(Future<void>&& f) {
666   Baton<> baton;
667   auto done = f.then([&](Try<void> &&t) {
668     baton.post();
669     t.value();
670   });
671   baton.wait();
672   while (!done.isReady()) {
673     // There's a race here between the return here and the actual finishing of
674     // the future. f is completed, but the setup may not have finished on done
675     // after the baton has posted.
676     std::this_thread::yield();
677   }
678   return done;
679 }
680
681 template <typename T, class Dur>
682 Future<T>
683 waitWithSemaphore(Future<T>&& f, Dur timeout) {
684   auto baton = std::make_shared<Baton<>>();
685   auto done = f.then([baton](Try<T> &&t) {
686     baton->post();
687     return std::move(t.value());
688   });
689   baton->timed_wait(std::chrono::system_clock::now() + timeout);
690   return done;
691 }
692
693 template <class Dur>
694 Future<void>
695 waitWithSemaphore(Future<void>&& f, Dur timeout) {
696   auto baton = std::make_shared<Baton<>>();
697   auto done = f.then([baton](Try<void> &&t) {
698     baton->post();
699     t.value();
700   });
701   baton->timed_wait(std::chrono::system_clock::now() + timeout);
702   return done;
703 }
704
705 namespace {
706   template <class T>
707   void getWaitHelper(Future<T>* f) {
708     // If we already have a value do the cheap thing
709     if (f->isReady()) {
710       return;
711     }
712
713     folly::Baton<> baton;
714     f->then([&](Try<T> const&) {
715       baton.post();
716     });
717     baton.wait();
718   }
719
720   template <class T>
721   Future<T> getWaitTimeoutHelper(Future<T>* f, Duration dur) {
722     // TODO make and use variadic whenAny #5877971
723     Promise<T> p;
724     auto token = std::make_shared<std::atomic<bool>>();
725     folly::Baton<> baton;
726
727     folly::detail::getTimekeeperSingleton()->after(dur)
728       .then([&,token](Try<void> const& t) {
729         if (token->exchange(true) == false) {
730           try {
731             t.value();
732             p.setException(TimedOut());
733           } catch (std::exception const& e) {
734             p.setException(exception_wrapper(std::current_exception(), e));
735           } catch (...) {
736             p.setException(exception_wrapper(std::current_exception()));
737           }
738           baton.post();
739         }
740       });
741
742     f->then([&, token](Try<T>&& t) {
743       if (token->exchange(true) == false) {
744         p.fulfilTry(std::move(t));
745         baton.post();
746       }
747     });
748
749     baton.wait();
750     return p.getFuture();
751   }
752 }
753
754 template <class T>
755 T Future<T>::get() {
756   getWaitHelper(this);
757
758   // Big assumption here: the then() call above, since it doesn't move out
759   // the value, leaves us with a value to return here. This would be a big
760   // no-no in user code, but I'm invoking internal developer privilege. This
761   // is slightly more efficient (save a move()) especially if there's an
762   // exception (save a throw).
763   return std::move(value());
764 }
765
766 template <>
767 inline void Future<void>::get() {
768   getWaitHelper(this);
769   value();
770 }
771
772 template <class T>
773 T Future<T>::get(Duration dur) {
774   return std::move(getWaitTimeoutHelper(this, dur).value());
775 }
776
777 template <>
778 inline void Future<void>::get(Duration dur) {
779   getWaitTimeoutHelper(this, dur).value();
780 }
781
782 template <class T>
783 T Future<T>::getVia(DrivableExecutor* e) {
784   while (!isReady()) {
785     e->drive();
786   }
787   return std::move(value());
788 }
789
790 template <>
791 inline void Future<void>::getVia(DrivableExecutor* e) {
792   while (!isReady()) {
793     e->drive();
794   }
795   value();
796 }
797
798 template <class T>
799 Future<T> Future<T>::within(Duration dur, Timekeeper* tk) {
800   return within(dur, TimedOut(), tk);
801 }
802
803 template <class T>
804 template <class E>
805 Future<T> Future<T>::within(Duration dur, E e, Timekeeper* tk) {
806
807   struct Context {
808     Context(E ex) : exception(std::move(ex)), promise(), token(false) {}
809     E exception;
810     Promise<T> promise;
811     std::atomic<bool> token;
812   };
813   auto ctx = std::make_shared<Context>(std::move(e));
814
815   if (!tk) {
816     tk = folly::detail::getTimekeeperSingleton();
817   }
818
819   tk->after(dur)
820     .then([ctx](Try<void> const& t) {
821       if (ctx->token.exchange(true) == false) {
822         try {
823           t.throwIfFailed();
824           ctx->promise.setException(std::move(ctx->exception));
825         } catch (std::exception const& e2) {
826           ctx->promise.setException(
827               exception_wrapper(std::current_exception(), e2));
828         } catch (...) {
829           ctx->promise.setException(
830               exception_wrapper(std::current_exception()));
831         }
832       }
833     });
834
835   this->then([ctx](Try<T>&& t) {
836     if (ctx->token.exchange(true) == false) {
837       ctx->promise.fulfilTry(std::move(t));
838     }
839   });
840
841   return ctx->promise.getFuture();
842 }
843
844 template <class T>
845 Future<T> Future<T>::delayed(Duration dur, Timekeeper* tk) {
846   return whenAll(*this, futures::sleep(dur, tk))
847     .then([](std::tuple<Try<T>, Try<void>> tup) {
848       Try<T>& t = std::get<0>(tup);
849       return makeFuture<T>(std::move(t));
850     });
851 }
852
853 template <class T>
854 Future<T> Future<T>::wait() {
855   Baton<> baton;
856   auto done = then([&](Try<T> t) {
857     baton.post();
858     return makeFuture(std::move(t));
859   });
860   baton.wait();
861   while (!done.isReady()) {
862     // There's a race here between the return here and the actual finishing of
863     // the future. f is completed, but the setup may not have finished on done
864     // after the baton has posted.
865     std::this_thread::yield();
866   }
867   return done;
868 }
869
870 template <class T>
871 Future<T> Future<T>::wait(Duration dur) {
872   auto baton = std::make_shared<Baton<>>();
873   auto done = then([baton](Try<T> t) {
874     baton->post();
875     return makeFuture(std::move(t));
876   });
877   baton->timed_wait(std::chrono::system_clock::now() + dur);
878   return done;
879 }
880
881 template <class T>
882 Future<T>& Future<T>::waitVia(DrivableExecutor* e) & {
883   while (!isReady()) {
884     e->drive();
885   }
886   return *this;
887 }
888
889 template <class T>
890 Future<T> Future<T>::waitVia(DrivableExecutor* e) && {
891   while (!isReady()) {
892     e->drive();
893   }
894   return std::move(*this);
895 }
896
897 }
898
899 // I haven't included a Future<T&> specialization because I don't forsee us
900 // using it, however it is not difficult to add when needed. Refer to
901 // Future<void> for guidance. std::future and boost::future code would also be
902 // instructive.