proxygen
Future-inl.h
Go to the documentation of this file.
1 /*
2  * Copyright 2014-present 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 #pragma once
17 
18 #include <algorithm>
19 #include <cassert>
20 #include <chrono>
21 #include <thread>
22 
23 #include <folly/Optional.h>
28 
29 #ifndef FOLLY_FUTURE_USING_FIBER
30 #if FOLLY_MOBILE || defined(__APPLE__)
31 #define FOLLY_FUTURE_USING_FIBER 0
32 #else
33 #define FOLLY_FUTURE_USING_FIBER 1
34 #include <folly/fibers/Baton.h>
35 #endif
36 #endif
37 
38 namespace folly {
39 
40 class Timekeeper;
41 
42 namespace futures {
43 namespace detail {
44 #if FOLLY_FUTURE_USING_FIBER
46 #else
48 #endif
49 } // namespace detail
50 } // namespace futures
51 
52 namespace detail {
53 std::shared_ptr<Timekeeper> getTimekeeperSingleton();
54 } // namespace detail
55 
56 namespace futures {
57 namespace detail {
58 // Guarantees that the stored functor is destructed before the stored promise
59 // may be fulfilled. Assumes the stored functor to be noexcept-destructible.
60 template <typename T, typename F>
62  using DF = _t<std::decay<F>>;
63 
64  public:
65  CoreCallbackState(Promise<T>&& promise, F&& func) noexcept(
66  noexcept(DF(std::declval<F&&>())))
67  : func_(std::forward<F>(func)), promise_(std::move(promise)) {
68  assert(before_barrier());
69  }
70 
72  noexcept(DF(std::declval<F&&>()))) {
73  if (that.before_barrier()) {
74  new (&func_) DF(std::forward<F>(that.func_));
75  promise_ = that.stealPromise();
76  }
77  }
78 
79  CoreCallbackState& operator=(CoreCallbackState&&) = delete;
80 
82  if (before_barrier()) {
83  stealPromise();
84  }
85  }
86 
87  template <typename... Args>
88  auto invoke(Args&&... args) noexcept(
89  noexcept(std::declval<F&&>()(std::declval<Args&&>()...))) {
90  assert(before_barrier());
91  return std::forward<F>(func_)(std::forward<Args>(args)...);
92  }
93 
94  template <typename... Args>
95  auto tryInvoke(Args&&... args) noexcept {
96  return makeTryWith([&] { return invoke(std::forward<Args>(args)...); });
97  }
98 
99  void setTry(Try<T>&& t) {
100  stealPromise().setTry(std::move(t));
101  }
102 
104  stealPromise().setException(std::move(ew));
105  }
106 
108  assert(before_barrier());
109  func_.~DF();
110  return std::move(promise_);
111  }
112 
113  private:
115  return !promise_.isFulfilled();
116  }
117 
118  union {
120  };
122 };
123 
124 template <typename T, typename F>
127  std::declval<Promise<T>&&>(),
128  std::declval<F&&>()))) {
129  return CoreCallbackState<T, F>(std::move(p), std::forward<F>(f));
130 }
131 
132 template <typename T, typename R, typename... Args>
134  return CoreCallbackState<T, R (*)(Args...)>(std::move(p), &f);
135 }
136 
137 template <class T>
138 FutureBase<T>::FutureBase(SemiFuture<T>&& other) noexcept : core_(other.core_) {
139  other.core_ = nullptr;
140 }
141 
142 template <class T>
143 FutureBase<T>::FutureBase(Future<T>&& other) noexcept : core_(other.core_) {
144  other.core_ = nullptr;
145 }
146 
147 template <class T>
148 template <class T2, typename>
150  : core_(Core::make(Try<T>(std::forward<T2>(val)))) {}
151 
152 template <class T>
153 template <typename T2>
155  typename std::enable_if<std::is_same<Unit, T2>::value>::type*)
156  : core_(Core::make(Try<T>(T()))) {}
157 
158 template <class T>
159 template <
160  class... Args,
161  typename std::enable_if<std::is_constructible<T, Args&&...>::value, int>::
162  type>
164  : core_(Core::make(in_place, std::forward<Args>(args)...)) {}
165 
166 template <class T>
168  detach();
169  core_ = exchange(other.core_, nullptr);
170 }
171 
172 template <class T>
174  detach();
175 }
176 
177 template <class T>
179  return result().value();
180 }
181 
182 template <class T>
184  return result().value();
185 }
186 
187 template <class T>
188 T&& FutureBase<T>::value() && {
189  return std::move(result().value());
190 }
191 
192 template <class T>
193 T const&& FutureBase<T>::value() const&& {
194  return std::move(result().value());
195 }
196 
197 template <class T>
199  return getCoreTryChecked();
200 }
201 
202 template <class T>
204  return getCoreTryChecked();
205 }
206 
207 template <class T>
209  return std::move(getCoreTryChecked());
210 }
211 
212 template <class T>
213 Try<T> const&& FutureBase<T>::result() const&& {
214  return std::move(getCoreTryChecked());
215 }
216 
217 template <class T>
219  return getCore().hasResult();
220 }
221 
222 template <class T>
224  return result().hasValue();
225 }
226 
227 template <class T>
229  return result().hasException();
230 }
231 
232 template <class T>
234  if (core_) {
235  core_->detachFuture();
236  core_ = nullptr;
237  }
238 }
239 
240 template <class T>
242  if (!core_) {
243  throw_exception<FutureInvalid>();
244  }
245 }
246 
247 template <class T>
249  if (!core_ || core_->hasCallback()) {
250  throw_exception<FutureAlreadyContinued>();
251  }
252 }
253 
254 template <class T>
256  auto& core = getCore();
257  return core.hasResult() ? Optional<Try<T>>(std::move(core.getTry()))
258  : Optional<Try<T>>();
259 }
260 
261 template <class T>
263  getCore().raise(std::move(exception));
264 }
265 
266 template <class T>
267 template <class F>
270  getCore().setCallback(std::forward<F>(func), RequestContext::saveContext());
271 }
272 
273 template <class T>
275  : core_(nullptr) {}
276 
277 // MSVC 2017 Update 7 released with a bug that causes issues expanding to an
278 // empty parameter pack when invoking a templated member function. It should
279 // be fixed for MSVC 2017 Update 8.
280 // TODO: Remove.
281 namespace detail_msvc_15_7_workaround {
282 template <typename R, std::size_t S>
283 using IfArgsSizeIs = std::enable_if_t<R::Arg::ArgsSize::value == S, int>;
284 template <typename R, typename State, typename T, IfArgsSizeIs<R, 0> = 0>
285 decltype(auto) invoke(R, State& state, Try<T>& /* t */) {
286  return state.invoke();
287 }
288 template <typename R, typename State, typename T, IfArgsSizeIs<R, 1> = 0>
289 decltype(auto) invoke(R, State& state, Try<T>& t) {
290  using Arg0 = typename R::Arg::ArgList::FirstArg;
291  return state.invoke(t.template get<R::Arg::isTry(), Arg0>());
292 }
293 template <typename R, typename State, typename T, IfArgsSizeIs<R, 0> = 0>
294 decltype(auto) tryInvoke(R, State& state, Try<T>& /* t */) {
295  return state.tryInvoke();
296 }
297 template <typename R, typename State, typename T, IfArgsSizeIs<R, 1> = 0>
298 decltype(auto) tryInvoke(R, State& state, Try<T>& t) {
299  using Arg0 = typename R::Arg::ArgList::FirstArg;
300  return state.tryInvoke(t.template get<R::Arg::isTry(), Arg0>());
301 }
302 } // namespace detail_msvc_15_7_workaround
303 
304 // then
305 
306 // Variant: returns a value
307 // e.g. f.then([](Try<T>&& t){ return t.value(); });
308 template <class T>
309 template <typename F, typename R>
312  static_assert(
313  R::Arg::ArgsSize::value <= 1, "Then must take zero/one argument");
314  typedef typename R::ReturnsFuture::Inner B;
315 
316  Promise<B> p;
317  p.core_->setInterruptHandlerNoLock(this->getCore().getInterruptHandler());
318 
319  // grab the Future now before we lose our handle on the Promise
320  auto sf = p.getSemiFuture();
321  sf.setExecutor(this->getExecutor());
322  auto f = Future<B>(sf.core_);
323  sf.core_ = nullptr;
324 
325  /* This is a bit tricky.
326 
327  We can't just close over *this in case this Future gets moved. So we
328  make a new dummy Future. We could figure out something more
329  sophisticated that avoids making a new Future object when it can, as an
330  optimization. But this is correct.
331 
332  core_ can't be moved, it is explicitly disallowed (as is copying). But
333  if there's ever a reason to allow it, this is one place that makes that
334  assumption and would need to be fixed. We use a standard shared pointer
335  for core_ (by copying it in), which means in essence obj holds a shared
336  pointer to itself. But this shouldn't leak because Promise will not
337  outlive the continuation, because Promise will setException() with a
338  broken Promise if it is destructed before completed. We could use a
339  weak pointer but it would have to be converted to a shared pointer when
340  func is executed (because the Future returned by func may possibly
341  persist beyond the callback, if it gets moved), and so it is an
342  optimization to just make it shared from the get-go.
343 
344  Two subtle but important points about this design. futures::detail::Core
345  has no back pointers to Future or Promise, so if Future or Promise get
346  moved (and they will be moved in performant code) we don't have to do
347  anything fancy. And because we store the continuation in the
348  futures::detail::Core, not in the Future, we can execute the continuation
349  even after the Future has gone out of scope. This is an intentional design
350  decision. It is likely we will want to be able to cancel a continuation
351  in some circumstances, but I think it should be explicit not implicit
352  in the destruction of the Future used to create it.
353  */
354  this->setCallback_(
356  std::move(p), std::forward<F>(func))](Try<T>&& t) mutable {
357  if (!R::Arg::isTry() && t.hasException()) {
358  state.setException(std::move(t.exception()));
359  } else {
360  state.setTry(makeTryWith([&] {
362  }));
363  }
364  });
365  return f;
366 }
367 
368 // Pass through a simple future as it needs no deferral adaptation
369 template <class T>
371  return std::move(f);
372 }
373 
374 // Correctly chain a SemiFuture for deferral
375 template <class T>
377  if (!e) {
379  }
380  return std::move(f).via(e);
381 }
382 
383 // Variant: returns a Future
384 // e.g. f.then([](T&& t){ return makeFuture<T>(t); });
385 template <class T>
386 template <typename F, typename R>
389  static_assert(
390  R::Arg::ArgsSize::value <= 1, "Then must take zero/one argument");
391  typedef typename R::ReturnsFuture::Inner B;
392 
393  Promise<B> p;
394  p.core_->setInterruptHandlerNoLock(this->getCore().getInterruptHandler());
395 
396  // grab the Future now before we lose our handle on the Promise
397  auto sf = p.getSemiFuture();
398  auto* e = this->getExecutor();
399  sf.setExecutor(e);
400  auto f = Future<B>(sf.core_);
401  sf.core_ = nullptr;
402 
403  this->setCallback_(
405  std::move(p), std::forward<F>(func))](Try<T>&& t) mutable {
406  if (!R::Arg::isTry() && t.hasException()) {
407  state.setException(std::move(t.exception()));
408  } else {
409  // Ensure that if function returned a SemiFuture we correctly chain
410  // potential deferral.
412  if (tf2.hasException()) {
413  state.setException(std::move(tf2.exception()));
414  } else {
415  auto statePromise = state.stealPromise();
416  auto tf3 = chainExecutor(
417  statePromise.core_->getExecutor(), *std::move(tf2));
418  std::exchange(statePromise.core_, nullptr)
419  ->setProxy(std::exchange(tf3.core_, nullptr));
420  }
421  }
422  });
423 
424  return f;
425 }
426 
427 template <class T>
428 template <typename E>
431  struct Context {
432  explicit Context(E ex) : exception(std::move(ex)) {}
433  E exception;
434  Future<Unit> thisFuture;
435  Promise<T> promise;
436  std::atomic<bool> token{false};
437  };
438 
439  std::shared_ptr<Timekeeper> tks;
440  if (LIKELY(!tk)) {
442  tk = tks.get();
443  }
444 
445  if (UNLIKELY(!tk)) {
446  return makeSemiFuture<T>(FutureNoTimekeeper());
447  }
448 
449  auto ctx = std::make_shared<Context>(std::move(e));
450 
451  auto f = [ctx](Try<T>&& t) {
452  if (!ctx->token.exchange(true, std::memory_order_relaxed)) {
453  ctx->promise.setTry(std::move(t));
454  }
455  };
457  ctx->thisFuture = this->thenImplementation(std::move(f), R{});
458 
459  // Properly propagate interrupt values through futures chained after within()
460  ctx->promise.setInterruptHandler(
461  [weakCtx = to_weak_ptr(ctx)](const exception_wrapper& ex) {
462  if (auto lockedCtx = weakCtx.lock()) {
463  lockedCtx->thisFuture.raise(ex);
464  }
465  });
466 
467  // Have time keeper use a weak ptr to hold ctx,
468  // so that ctx can be deallocated as soon as the future job finished.
469  tk->after(dur).thenTry([weakCtx = to_weak_ptr(ctx)](Try<Unit>&& t) mutable {
470  auto lockedCtx = weakCtx.lock();
471  if (!lockedCtx) {
472  // ctx already released. "this" completed first, cancel "after"
473  return;
474  }
475  // "after" completed first, cancel "this"
476  lockedCtx->thisFuture.raise(FutureTimeout());
477  if (!lockedCtx->token.exchange(true, std::memory_order_relaxed)) {
478  if (t.hasException()) {
479  lockedCtx->promise.setException(std::move(t.exception()));
480  } else {
481  lockedCtx->promise.setException(std::move(lockedCtx->exception));
482  }
483  }
484  });
485 
486  return ctx->promise.getSemiFuture();
487 }
488 
497 class DeferredExecutor final : public Executor {
498  public:
499  void add(Func func) override {
500  auto state = state_.load(std::memory_order_acquire);
501  if (state == State::DETACHED) {
502  return;
503  }
504  if (state == State::HAS_EXECUTOR) {
505  executor_->add(std::move(func));
506  return;
507  }
508  DCHECK(state == State::EMPTY);
509  func_ = std::move(func);
510  if (state_.compare_exchange_strong(
511  state,
512  State::HAS_FUNCTION,
513  std::memory_order_release,
514  std::memory_order_acquire)) {
515  return;
516  }
517  DCHECK(state == State::DETACHED || state == State::HAS_EXECUTOR);
518  if (state == State::DETACHED) {
519  std::exchange(func_, nullptr);
520  return;
521  }
522  executor_->add(std::exchange(func_, nullptr));
523  }
524 
526  if (nestedExecutors_) {
527  auto nestedExecutors = std::exchange(nestedExecutors_, nullptr);
528  for (auto& nestedExecutor : *nestedExecutors) {
529  nestedExecutor->setExecutor(executor.copy());
530  }
531  }
532  executor_ = std::move(executor);
533  auto state = state_.load(std::memory_order_acquire);
534  if (state == State::EMPTY &&
535  state_.compare_exchange_strong(
536  state,
537  State::HAS_EXECUTOR,
538  std::memory_order_release,
539  std::memory_order_acquire)) {
540  return;
541  }
542 
543  DCHECK(state == State::HAS_FUNCTION);
544  state_.store(State::HAS_EXECUTOR, std::memory_order_release);
545  executor_->add(std::exchange(func_, nullptr));
546  }
547 
548  void detach() {
549  if (nestedExecutors_) {
550  auto nestedExecutors = std::exchange(nestedExecutors_, nullptr);
551  for (auto& nestedExecutor : *nestedExecutors) {
552  nestedExecutor->detach();
553  }
554  }
555  auto state = state_.load(std::memory_order_acquire);
556  if (state == State::EMPTY &&
557  state_.compare_exchange_strong(
558  state,
559  State::DETACHED,
560  std::memory_order_release,
561  std::memory_order_acquire)) {
562  return;
563  }
564 
565  DCHECK(state == State::HAS_FUNCTION);
566  state_.store(State::DETACHED, std::memory_order_release);
567  std::exchange(func_, nullptr);
568  }
569 
571  std::vector<folly::Executor::KeepAlive<DeferredExecutor>> executors) {
572  DCHECK(!nestedExecutors_);
573  nestedExecutors_ = std::make_unique<
574  std::vector<folly::Executor::KeepAlive<DeferredExecutor>>>(
575  std::move(executors));
576  }
577 
579  return makeKeepAlive<DeferredExecutor>(new DeferredExecutor());
580  }
581 
582  private:
584 
585  bool keepAliveAcquire() override {
586  auto keepAliveCount =
587  keepAliveCount_.fetch_add(1, std::memory_order_relaxed);
588  DCHECK(keepAliveCount > 0);
589  return true;
590  }
591 
592  void keepAliveRelease() override {
593  auto keepAliveCount =
594  keepAliveCount_.fetch_sub(1, std::memory_order_acq_rel);
595  DCHECK(keepAliveCount > 0);
596  if (keepAliveCount == 1) {
597  delete this;
598  }
599  }
600 
601  enum class State { EMPTY, HAS_FUNCTION, HAS_EXECUTOR, DETACHED };
602  std::atomic<State> state_{State::EMPTY};
605  std::unique_ptr<std::vector<folly::Executor::KeepAlive<DeferredExecutor>>>
607  std::atomic<ssize_t> keepAliveCount_{1};
608 };
609 
610 class WaitExecutor final : public folly::Executor {
611  public:
612  void add(Func func) override {
613  auto wQueue = queue_.wlock();
614  if (wQueue->detached) {
615  return;
616  }
617  bool empty = wQueue->funcs.empty();
618  wQueue->funcs.push_back(std::move(func));
619  if (empty) {
620  baton_.post();
621  }
622  }
623 
624  void drive() {
625  baton_.wait();
626  baton_.reset();
627  auto funcs = std::move(queue_.wlock()->funcs);
628  for (auto& func : funcs) {
629  std::exchange(func, nullptr)();
630  }
631  }
632 
633  using Clock = std::chrono::steady_clock;
634 
635  bool driveUntil(Clock::time_point deadline) {
636  if (!baton_.try_wait_until(deadline)) {
637  return false;
638  }
639  baton_.reset();
640  auto funcs = std::move(queue_.wlock()->funcs);
641  for (auto& func : funcs) {
642  std::exchange(func, nullptr)();
643  }
644  return true;
645  }
646 
647  void detach() {
648  // Make sure we don't hold the lock while destroying funcs.
649  [&] {
650  auto wQueue = queue_.wlock();
651  wQueue->detached = true;
652  return std::move(wQueue->funcs);
653  }();
654  }
655 
657  return makeKeepAlive<WaitExecutor>(new WaitExecutor());
658  }
659 
660  private:
662 
663  bool keepAliveAcquire() override {
664  auto keepAliveCount =
665  keepAliveCount_.fetch_add(1, std::memory_order_relaxed);
666  DCHECK(keepAliveCount > 0);
667  return true;
668  }
669 
670  void keepAliveRelease() override {
671  auto keepAliveCount =
672  keepAliveCount_.fetch_sub(1, std::memory_order_acq_rel);
673  DCHECK(keepAliveCount > 0);
674  if (keepAliveCount == 1) {
675  delete this;
676  }
677  }
678 
679  struct Queue {
680  std::vector<Func> funcs;
681  bool detached{false};
682  };
683 
686 
687  std::atomic<ssize_t> keepAliveCount_{1};
688 };
689 
690 // Vector-like structure to play with window,
691 // which otherwise expects a vector of size `times`,
692 // which would be expensive with large `times` sizes.
694  using iterator = std::vector<size_t>::iterator;
695 
696  WindowFakeVector(size_t size) : size_(size) {}
697 
698  size_t operator[](const size_t index) const {
699  return index;
700  }
701  size_t size() const {
702  return size_;
703  }
704 
705  private:
706  size_t size_;
707 };
708 } // namespace detail
709 } // namespace futures
710 
711 template <class T>
713  return makeSemiFuture(Try<typename std::decay<T>::type>(std::forward<T>(t)));
714 }
715 
716 // makeSemiFutureWith(SemiFuture<T>()) -> SemiFuture<T>
717 template <class F>
718 typename std::enable_if<
722  using InnerType = typename isFutureOrSemiFuture<invoke_result_t<F>>::Inner;
723  try {
724  return std::forward<F>(func)();
725  } catch (std::exception& e) {
726  return makeSemiFuture<InnerType>(
727  exception_wrapper(std::current_exception(), e));
728  } catch (...) {
729  return makeSemiFuture<InnerType>(
730  exception_wrapper(std::current_exception()));
731  }
732 }
733 
734 // makeSemiFutureWith(T()) -> SemiFuture<T>
735 // makeSemiFutureWith(void()) -> SemiFuture<Unit>
736 template <class F>
737 typename std::enable_if<
741  using LiftedResult = lift_unit_t<invoke_result_t<F>>;
742  return makeSemiFuture<LiftedResult>(
743  makeTryWith([&func]() mutable { return std::forward<F>(func)(); }));
744 }
745 
746 template <class T>
747 SemiFuture<T> makeSemiFuture(std::exception_ptr const& e) {
748  return makeSemiFuture(Try<T>(e));
749 }
750 
751 template <class T>
753  return makeSemiFuture(Try<T>(std::move(ew)));
754 }
755 
756 template <class T, class E>
757 typename std::
759  makeSemiFuture(E const& e) {
760  return makeSemiFuture(Try<T>(make_exception_wrapper<E>(e)));
761 }
762 
763 template <class T>
766 }
767 
768 // This must be defined after the constructors to avoid a bug in MSVC
769 // https://connect.microsoft.com/VisualStudio/feedback/details/3142777/out-of-line-constructor-definition-after-implicit-reference-causes-incorrect-c2244
771  return makeSemiFuture(Unit{});
772 }
773 
774 template <class T>
777 }
778 
779 template <class T>
781  const {
782  if (auto executor = this->getExecutor()) {
783  assert(dynamic_cast<DeferredExecutor*>(executor) != nullptr);
784  return static_cast<DeferredExecutor*>(executor);
785  }
786  return nullptr;
787 }
788 
789 template <class T>
792  if (auto executor = this->getExecutor()) {
793  assert(dynamic_cast<DeferredExecutor*>(executor) != nullptr);
794  auto executorKeepAlive =
795  folly::getKeepAliveToken(static_cast<DeferredExecutor*>(executor));
796  this->core_->setExecutor(nullptr);
797  return executorKeepAlive;
798  }
799  return {};
800 }
801 
802 template <class T>
804  if (!core) {
805  return;
806  }
807  if (auto executor = core->getExecutor()) {
808  assert(dynamic_cast<DeferredExecutor*>(executor) != nullptr);
809  static_cast<DeferredExecutor*>(executor)->detach();
810  core->setExecutor(nullptr);
811  }
812 }
813 
814 template <class T>
816  releaseDeferredExecutor(this->core_);
817 }
818 
819 template <class T>
821  : futures::detail::FutureBase<T>(std::move(other)) {}
822 
823 template <class T>
825  : futures::detail::FutureBase<T>(std::move(other)) {
826  // SemiFuture should not have an executor on construction
827  if (this->core_) {
828  this->setExecutor(nullptr);
829  }
830 }
831 
832 template <class T>
834  releaseDeferredExecutor(this->core_);
835  this->assign(std::move(other));
836  return *this;
837 }
838 
839 template <class T>
841  releaseDeferredExecutor(this->core_);
842  this->assign(std::move(other));
843  // SemiFuture should not have an executor on construction
844  if (this->core_) {
845  this->setExecutor(nullptr);
846  }
847  return *this;
848 }
849 
850 template <class T>
853  int8_t priority) && {
854  if (!executor) {
855  throw_exception<FutureNoExecutor>();
856  }
857 
858  if (auto deferredExecutor = getDeferredExecutor()) {
859  deferredExecutor->setExecutor(executor.copy());
860  }
861 
862  auto newFuture = Future<T>(this->core_);
863  this->core_ = nullptr;
864  newFuture.setExecutor(std::move(executor), priority);
865 
866  return newFuture;
867 }
868 
869 template <class T>
871  return std::move(*this).via(getKeepAliveToken(executor), priority);
872 }
873 
874 template <class T>
876  return std::move(*this).via(&InlineExecutor::instance());
877 }
878 
879 template <class T>
880 template <typename F>
882 SemiFuture<T>::defer(F&& func) && {
883  DeferredExecutor* deferredExecutor = getDeferredExecutor();
884  if (!deferredExecutor) {
885  auto newDeferredExecutor = DeferredExecutor::create();
886  deferredExecutor = newDeferredExecutor.get();
887  this->setExecutor(std::move(newDeferredExecutor));
888  }
889 
890  auto sf = Future<T>(this->core_).thenTry(std::forward<F>(func)).semi();
891  this->core_ = nullptr;
892  // Carry deferred executor through chain as constructor from Future will
893  // nullify it
894  sf.setExecutor(deferredExecutor);
895  return sf;
896 }
897 
898 template <class T>
899 template <typename F>
902  return std::move(*this).defer([f = std::forward<F>(func)](
903  folly::Try<T>&& t) mutable {
904  return std::forward<F>(f)(
905  t.template get<
906  false,
907  typename futures::detail::valueCallableResult<T, F>::FirstArg>());
908  });
909 }
910 
911 template <class T>
912 template <class ExceptionType, class F>
914  return std::move(*this).defer(
915  [func = std::forward<F>(func)](Try<T>&& t) mutable {
916  if (auto e = t.template tryGetExceptionObject<ExceptionType>()) {
917  return makeSemiFutureWith(
918  [&]() mutable { return std::forward<F>(func)(*e); });
919  } else {
920  return makeSemiFuture<T>(std::move(t));
921  }
922  });
923 }
924 
925 template <class T>
926 template <class F>
928  return std::move(*this).defer(
929  [func = std::forward<F>(func)](Try<T> t) mutable {
930  if (t.hasException()) {
931  return makeSemiFutureWith([&]() mutable {
932  return std::forward<F>(func)(std::move(t.exception()));
933  });
934  } else {
935  return makeSemiFuture<T>(std::move(t));
936  }
937  });
938 }
939 
940 template <typename T>
942  return collectAllSemiFuture(*this, futures::sleep(dur, tk))
943  .toUnsafeFuture()
944  .thenValue([](std::tuple<Try<T>, Try<Unit>> tup) {
945  Try<T>& t = std::get<0>(tup);
946  return makeFuture<T>(std::move(t));
947  });
948 }
949 
950 template <class T>
953 }
954 
955 template <class T>
957  : futures::detail::FutureBase<T>(std::move(other)) {}
958 
959 template <class T>
961  this->assign(std::move(other));
962  return *this;
963 }
964 
965 template <class T>
966 template <
967  class T2,
968  typename std::enable_if<
972  int>::type>
974  : Future(
975  std::move(other).thenValue([](T2&& v) { return T(std::move(v)); })) {}
976 
977 template <class T>
978 template <
979  class T2,
980  typename std::enable_if<
983  !std::is_convertible<T2&&, T>::value,
984  int>::type>
986  : Future(
987  std::move(other).thenValue([](T2&& v) { return T(std::move(v)); })) {}
988 
989 template <class T>
990 template <
991  class T2,
992  typename std::enable_if<
995  int>::type>
997  return operator=(
998  std::move(other).thenValue([](T2&& v) { return T(std::move(v)); }));
999 }
1000 
1001 // unwrap
1002 
1003 template <class T>
1004 template <class F>
1005 typename std::
1008  return std::move(*this).thenValue(
1009  [](Future<typename isFuture<T>::Inner> internal_future) {
1010  return internal_future;
1011  });
1012 }
1013 
1014 template <class T>
1016  this->setExecutor(std::move(executor), priority);
1017 
1018  auto newFuture = Future<T>(this->core_);
1019  this->core_ = nullptr;
1020  return newFuture;
1021 }
1022 
1023 template <class T>
1025  return std::move(*this).via(getKeepAliveToken(executor), priority);
1026 }
1027 
1028 template <class T>
1030  this->throwIfInvalid();
1031  Promise<T> p;
1032  auto sf = p.getSemiFuture();
1033  auto func = [p = std::move(p)](Try<T>&& t) mutable {
1034  p.setTry(std::move(t));
1035  };
1037  this->thenImplementation(std::move(func), R{});
1038  // Construct future from semifuture manually because this may not have
1039  // an executor set due to legacy code. This means we can bypass the executor
1040  // check in SemiFuture::via
1041  auto f = Future<T>(sf.core_);
1042  sf.core_ = nullptr;
1043  return std::move(f).via(std::move(executor), priority);
1044 }
1045 
1046 template <class T>
1047 Future<T> Future<T>::via(Executor* executor, int8_t priority) & {
1048  return via(getKeepAliveToken(executor), priority);
1049 }
1050 
1051 template <typename T>
1052 template <typename R, typename Caller, typename... Args>
1054  R (Caller::*func)(Args...),
1055  Caller* instance) && {
1056  typedef typename std::remove_cv<typename std::remove_reference<
1057  typename futures::detail::ArgType<Args...>::FirstArg>::type>::type
1058  FirstArg;
1059 
1060  return std::move(*this).thenTry([instance, func](Try<T>&& t) {
1061  return (instance->*func)(t.template get<isTry<FirstArg>::value, Args>()...);
1062  });
1063 }
1064 
1065 template <class T>
1066 template <typename F>
1068 Future<T>::thenTry(F&& func) && {
1069  auto lambdaFunc = [f = std::forward<F>(func)](folly::Try<T>&& t) mutable {
1070  return std::forward<F>(f)(std::move(t));
1071  };
1073  return this->thenImplementation(std::move(lambdaFunc), R{});
1074 }
1075 
1076 template <class T>
1077 template <typename F>
1079 Future<T>::thenValue(F&& func) && {
1080  auto lambdaFunc = [f = std::forward<F>(func)](folly::Try<T>&& t) mutable {
1081  return std::forward<F>(f)(
1082  t.template get<
1083  false,
1085  };
1087  return this->thenImplementation(std::move(lambdaFunc), R{});
1088 }
1089 
1090 template <class T>
1091 template <class ExceptionType, class F>
1093  // Forward to onError but ensure that returned future carries the executor
1094  // Allow for applying to future with null executor while this is still
1095  // possible.
1096  auto* e = this->getExecutor();
1097  return std::move(*this)
1098  .onError([func = std::forward<F>(func)](ExceptionType& ex) mutable {
1099  return std::forward<F>(func)(ex);
1100  })
1101  .via(e ? e : &InlineExecutor::instance());
1102 }
1103 
1104 template <class T>
1105 template <class F>
1107  // Forward to onError but ensure that returned future carries the executor
1108  // Allow for applying to future with null executor while this is still
1109  // possible.
1110  auto* e = this->getExecutor();
1111  return std::move(*this)
1112  .onError([func = std::forward<F>(func)](
1113  folly::exception_wrapper&& ex) mutable {
1114  return std::forward<F>(func)(std::move(ex));
1115  })
1116  .via(e ? e : &InlineExecutor::instance());
1117 }
1118 
1119 template <class T>
1121  return std::move(*this).thenValue([](T&&) {});
1122 }
1123 
1124 // onError where the callback returns T
1125 template <class T>
1126 template <class F>
1127 typename std::enable_if<
1131 Future<T>::onError(F&& func) && {
1132  typedef std::remove_reference_t<
1134  Exn;
1135  static_assert(
1136  std::is_same<typename futures::detail::Extract<F>::RawReturn, T>::value,
1137  "Return type of onError callback must be T or Future<T>");
1138 
1139  Promise<T> p;
1140  p.core_->setInterruptHandlerNoLock(this->getCore().getInterruptHandler());
1141  auto sf = p.getSemiFuture();
1142 
1143  this->setCallback_(
1145  std::move(p), std::forward<F>(func))](Try<T>&& t) mutable {
1146  if (auto e = t.template tryGetExceptionObject<Exn>()) {
1147  state.setTry(makeTryWith([&] { return state.invoke(*e); }));
1148  } else {
1149  state.setTry(std::move(t));
1150  }
1151  });
1152 
1153  // Allow for applying to future with null executor while this is still
1154  // possible.
1155  // TODO(T26801487): Should have an executor
1156  return std::move(sf).via(&InlineExecutor::instance());
1157 }
1158 
1159 // onError where the callback returns Future<T>
1160 template <class T>
1161 template <class F>
1162 typename std::enable_if<
1166 Future<T>::onError(F&& func) && {
1167  static_assert(
1168  std::is_same<typename futures::detail::Extract<F>::Return, Future<T>>::
1169  value,
1170  "Return type of onError callback must be T or Future<T>");
1171  typedef std::remove_reference_t<
1173  Exn;
1174 
1175  Promise<T> p;
1176  auto sf = p.getSemiFuture();
1177 
1178  this->setCallback_(
1180  std::move(p), std::forward<F>(func))](Try<T>&& t) mutable {
1181  if (auto e = t.template tryGetExceptionObject<Exn>()) {
1182  auto tf2 = state.tryInvoke(*e);
1183  if (tf2.hasException()) {
1184  state.setException(std::move(tf2.exception()));
1185  } else {
1186  tf2->setCallback_([p = state.stealPromise()](Try<T>&& t3) mutable {
1187  p.setTry(std::move(t3));
1188  });
1189  }
1190  } else {
1191  state.setTry(std::move(t));
1192  }
1193  });
1194 
1195  // Allow for applying to future with null executor while this is still
1196  // possible.
1197  // TODO(T26801487): Should have an executor
1198  return std::move(sf).via(&InlineExecutor::instance());
1199 }
1200 
1201 template <class T>
1202 template <class F>
1204  return std::move(*this).thenTry(
1205  [funcw = std::forward<F>(func)](Try<T>&& t) mutable {
1206  std::forward<F>(funcw)();
1207  return makeFuture(std::move(t));
1208  });
1209 }
1210 
1211 template <class T>
1212 template <class F>
1214  return std::move(*this).within(dur, tk).template thenError<FutureTimeout>(
1215  [funcw = std::forward<F>(func)](auto const&) mutable {
1216  return std::forward<F>(funcw)();
1217  });
1218 }
1219 
1220 template <class T>
1221 template <class F>
1222 typename std::enable_if<
1226 Future<T>::onError(F&& func) && {
1227  static_assert(
1228  std::is_same<typename futures::detail::Extract<F>::Return, Future<T>>::
1229  value,
1230  "Return type of onError callback must be T or Future<T>");
1231 
1232  Promise<T> p;
1233  auto sf = p.getSemiFuture();
1234  this->setCallback_(
1236  std::move(p), std::forward<F>(func))](Try<T> t) mutable {
1237  if (t.hasException()) {
1238  auto tf2 = state.tryInvoke(std::move(t.exception()));
1239  if (tf2.hasException()) {
1240  state.setException(std::move(tf2.exception()));
1241  } else {
1242  tf2->setCallback_([p = state.stealPromise()](Try<T>&& t3) mutable {
1243  p.setTry(std::move(t3));
1244  });
1245  }
1246  } else {
1247  state.setTry(std::move(t));
1248  }
1249  });
1250 
1251  // Allow for applying to future with null executor while this is still
1252  // possible.
1253  // TODO(T26801487): Should have an executor
1254  return std::move(sf).via(&InlineExecutor::instance());
1255 }
1256 
1257 // onError(exception_wrapper) that returns T
1258 template <class T>
1259 template <class F>
1260 typename std::enable_if<
1262  !futures::detail::Extract<F>::ReturnsFuture::value,
1264 Future<T>::onError(F&& func) && {
1265  static_assert(
1266  std::is_same<typename futures::detail::Extract<F>::Return, Future<T>>::
1267  value,
1268  "Return type of onError callback must be T or Future<T>");
1269 
1270  Promise<T> p;
1271  auto sf = p.getSemiFuture();
1272  this->setCallback_(
1274  std::move(p), std::forward<F>(func))](Try<T>&& t) mutable {
1275  if (t.hasException()) {
1276  state.setTry(makeTryWith(
1277  [&] { return state.invoke(std::move(t.exception())); }));
1278  } else {
1279  state.setTry(std::move(t));
1280  }
1281  });
1282 
1283  // Allow for applying to future with null executor while this is still
1284  // possible.
1285  // TODO(T26801487): Should have an executor
1286  return std::move(sf).via(&InlineExecutor::instance());
1287 }
1288 
1289 template <class Func>
1290 auto via(Executor* x, Func&& func) -> Future<
1291  typename isFutureOrSemiFuture<decltype(std::declval<Func>()())>::Inner> {
1292  // TODO make this actually more performant. :-P #7260175
1293  return via(x).thenValue([f = std::forward<Func>(func)](auto&&) mutable {
1294  return std::forward<Func>(f)();
1295  });
1296 }
1297 
1298 template <class Func>
1300  typename isFutureOrSemiFuture<decltype(std::declval<Func>()())>::Inner> {
1301  return via(std::move(x))
1302  .thenValue([f = std::forward<Func>(func)](auto&&) mutable {
1303  return std::forward<Func>(f)();
1304  });
1305 }
1306 
1307 // makeFuture
1308 
1309 template <class T>
1311  return makeFuture(Try<typename std::decay<T>::type>(std::forward<T>(t)));
1312 }
1313 
1315  return makeFuture(Unit{});
1316 }
1317 
1318 // makeFutureWith(Future<T>()) -> Future<T>
1319 template <class F>
1320 typename std::
1321  enable_if<isFuture<invoke_result_t<F>>::value, invoke_result_t<F>>::type
1322  makeFutureWith(F&& func) {
1323  using InnerType = typename isFuture<invoke_result_t<F>>::Inner;
1324  try {
1325  return std::forward<F>(func)();
1326  } catch (std::exception& e) {
1327  return makeFuture<InnerType>(
1328  exception_wrapper(std::current_exception(), e));
1329  } catch (...) {
1330  return makeFuture<InnerType>(exception_wrapper(std::current_exception()));
1331  }
1332 }
1333 
1334 // makeFutureWith(T()) -> Future<T>
1335 // makeFutureWith(void()) -> Future<Unit>
1336 template <class F>
1337 typename std::enable_if<
1340 makeFutureWith(F&& func) {
1341  using LiftedResult = lift_unit_t<invoke_result_t<F>>;
1342  return makeFuture<LiftedResult>(
1343  makeTryWith([&func]() mutable { return std::forward<F>(func)(); }));
1344 }
1345 
1346 template <class T>
1347 Future<T> makeFuture(std::exception_ptr const& e) {
1348  return makeFuture(Try<T>(e));
1349 }
1350 
1351 template <class T>
1353  return makeFuture(Try<T>(std::move(ew)));
1354 }
1355 
1356 template <class T, class E>
1358  type
1359  makeFuture(E const& e) {
1360  return makeFuture(Try<T>(make_exception_wrapper<E>(e)));
1361 }
1362 
1363 template <class T>
1366 }
1367 
1368 // via
1370  return makeFuture().via(executor, priority);
1371 }
1372 
1374  return makeFuture().via(std::move(executor), priority);
1375 }
1376 
1377 namespace futures {
1378 namespace detail {
1379 
1380 template <typename V, typename... Fs, std::size_t... Is>
1382 foreach_(index_sequence<Is...>, V&& v, Fs&&... fs) {
1383  using _ = int[];
1384  void(_{0, (void(v(index_constant<Is>{}, static_cast<Fs&&>(fs))), 0)...});
1385 }
1386 template <typename V, typename... Fs>
1388  V&& v,
1389  Fs&&... fs) {
1390  using _ = index_sequence_for<Fs...>;
1391  foreach_(_{}, static_cast<V&&>(v), static_cast<Fs&&>(fs)...);
1392 }
1393 
1394 template <typename T>
1396  return future.getDeferredExecutor();
1397 }
1398 
1399 template <typename T>
1401  SemiFuture<T>& future) {
1402  return future.stealDeferredExecutor();
1403 }
1404 
1405 template <typename T>
1407  return {};
1408 }
1409 
1410 template <typename... Ts>
1412  std::vector<folly::Executor::KeepAlive<DeferredExecutor>>& executors,
1413  Ts&... ts) {
1414  auto foreach = [&](auto& future) {
1415  if (auto executor = stealDeferredExecutor(future)) {
1416  executors.push_back(std::move(executor));
1417  }
1418  return folly::unit;
1419  };
1420  [](...) {}(foreach(ts)...);
1421 }
1422 
1423 template <class InputIterator>
1425  std::vector<folly::Executor::KeepAlive<DeferredExecutor>>& executors,
1426  InputIterator first,
1427  InputIterator last) {
1428  for (auto it = first; it != last; ++it) {
1429  if (auto executor = stealDeferredExecutor(*it)) {
1430  executors.push_back(std::move(executor));
1431  }
1432  }
1433 }
1434 } // namespace detail
1435 } // namespace futures
1436 
1437 // collectAll (variadic)
1438 
1439 template <typename... Fs>
1442  using Result = std::tuple<Try<typename remove_cvref_t<Fs>::value_type>...>;
1443  struct Context {
1444  ~Context() {
1445  p.setValue(std::move(results));
1446  }
1447  Promise<Result> p;
1448  Result results;
1449  };
1450 
1451  std::vector<folly::Executor::KeepAlive<futures::detail::DeferredExecutor>>
1452  executors;
1454 
1455  auto ctx = std::make_shared<Context>();
1457  [&](auto i, auto&& f) {
1458  f.setCallback_([i, ctx](auto&& t) {
1459  std::get<i.value>(ctx->results) = std::move(t);
1460  });
1461  },
1462  static_cast<Fs&&>(fs)...);
1463 
1464  auto future = ctx->p.getSemiFuture();
1465  if (!executors.empty()) {
1466  auto work = [](Try<typename decltype(future)::value_type>&& t) {
1467  return std::move(t).value();
1468  };
1469  future = std::move(future).defer(work);
1470  auto deferredExecutor = futures::detail::getDeferredExecutor(future);
1471  deferredExecutor->setNestedExecutors(std::move(executors));
1472  }
1473  return future;
1474 }
1475 
1476 template <typename... Fs>
1478  Fs&&... fs) {
1479  return collectAllSemiFuture(std::forward<Fs>(fs)...).toUnsafeFuture();
1480 }
1481 
1482 // collectAll (iterator)
1483 
1484 template <class InputIterator>
1485 SemiFuture<std::vector<
1487 collectAllSemiFuture(InputIterator first, InputIterator last) {
1488  using F = typename std::iterator_traits<InputIterator>::value_type;
1489  using T = typename F::value_type;
1490 
1491  struct Context {
1492  explicit Context(size_t n) : results(n) {}
1493  ~Context() {
1494  p.setValue(std::move(results));
1495  }
1497  std::vector<Try<T>> results;
1498  };
1499 
1500  std::vector<folly::Executor::KeepAlive<futures::detail::DeferredExecutor>>
1501  executors;
1502  futures::detail::stealDeferredExecutors(executors, first, last);
1503 
1504  auto ctx = std::make_shared<Context>(size_t(std::distance(first, last)));
1505 
1506  for (size_t i = 0; first != last; ++first, ++i) {
1507  first->setCallback_(
1508  [i, ctx](Try<T>&& t) { ctx->results[i] = std::move(t); });
1509  }
1510 
1511  auto future = ctx->p.getSemiFuture();
1512  if (!executors.empty()) {
1513  future = std::move(future).defer(
1514  [](Try<typename decltype(future)::value_type>&& t) {
1515  return std::move(t).value();
1516  });
1517  auto deferredExecutor = futures::detail::getDeferredExecutor(future);
1518  deferredExecutor->setNestedExecutors(std::move(executors));
1519  }
1520  return future;
1521 }
1522 
1523 template <class InputIterator>
1524 Future<std::vector<
1526 collectAll(InputIterator first, InputIterator last) {
1527  return collectAllSemiFuture(first, last).toUnsafeFuture();
1528 }
1529 
1530 // collect (iterator)
1531 
1532 // TODO(T26439406): Make return SemiFuture
1533 template <class InputIterator>
1534 Future<std::vector<
1535  typename std::iterator_traits<InputIterator>::value_type::value_type>>
1536 collect(InputIterator first, InputIterator last) {
1537  using F = typename std::iterator_traits<InputIterator>::value_type;
1538  using T = typename F::value_type;
1539 
1540  struct Context {
1541  explicit Context(size_t n) : result(n) {
1542  finalResult.reserve(n);
1543  }
1544  ~Context() {
1545  if (!threw.load(std::memory_order_relaxed)) {
1546  // map Optional<T> -> T
1548  result.begin(),
1549  result.end(),
1550  std::back_inserter(finalResult),
1551  [](Optional<T>& o) { return std::move(o.value()); });
1552  p.setValue(std::move(finalResult));
1553  }
1554  }
1556  std::vector<Optional<T>> result;
1557  std::vector<T> finalResult;
1558  std::atomic<bool> threw{false};
1559  };
1560 
1561  auto ctx = std::make_shared<Context>(std::distance(first, last));
1562  for (size_t i = 0; first != last; ++first, ++i) {
1563  first->setCallback_([i, ctx](Try<T>&& t) {
1564  if (t.hasException()) {
1565  if (!ctx->threw.exchange(true, std::memory_order_relaxed)) {
1566  ctx->p.setException(std::move(t.exception()));
1567  }
1568  } else if (!ctx->threw.load(std::memory_order_relaxed)) {
1569  ctx->result[i] = std::move(t.value());
1570  }
1571  });
1572  }
1573  return ctx->p.getSemiFuture().via(&InlineExecutor::instance());
1574 }
1575 
1576 // collect (variadic)
1577 
1578 // TODO(T26439406): Make return SemiFuture
1579 template <typename... Fs>
1581  Fs&&... fs) {
1582  using Result = std::tuple<typename remove_cvref_t<Fs>::value_type...>;
1583  struct Context {
1584  ~Context() {
1585  if (!threw.load(std::memory_order_relaxed)) {
1586  p.setValue(unwrapTryTuple(std::move(results)));
1587  }
1588  }
1589  Promise<Result> p;
1590  std::tuple<Try<typename remove_cvref_t<Fs>::value_type>...> results;
1591  std::atomic<bool> threw{false};
1592  };
1593 
1594  auto ctx = std::make_shared<Context>();
1596  [&](auto i, auto&& f) {
1597  f.setCallback_([i, ctx](auto&& t) {
1598  if (t.hasException()) {
1599  if (!ctx->threw.exchange(true, std::memory_order_relaxed)) {
1600  ctx->p.setException(std::move(t.exception()));
1601  }
1602  } else if (!ctx->threw.load(std::memory_order_relaxed)) {
1603  std::get<i.value>(ctx->results) = std::move(t);
1604  }
1605  });
1606  },
1607  static_cast<Fs&&>(fs)...);
1608  return ctx->p.getSemiFuture().via(&InlineExecutor::instance());
1609 }
1610 
1611 // collectAny (iterator)
1612 
1613 // TODO(T26439406): Make return SemiFuture
1614 template <class InputIterator>
1615 Future<std::pair<
1616  size_t,
1618 collectAny(InputIterator first, InputIterator last) {
1619  using F = typename std::iterator_traits<InputIterator>::value_type;
1620  using T = typename F::value_type;
1621 
1622  struct Context {
1624  std::atomic<bool> done{false};
1625  };
1626 
1627  auto ctx = std::make_shared<Context>();
1628  for (size_t i = 0; first != last; ++first, ++i) {
1629  first->setCallback_([i, ctx](Try<T>&& t) {
1630  if (!ctx->done.exchange(true, std::memory_order_relaxed)) {
1631  ctx->p.setValue(std::make_pair(i, std::move(t)));
1632  }
1633  });
1634  }
1635  return ctx->p.getSemiFuture().via(&InlineExecutor::instance());
1636 }
1637 
1638 // collectAnyWithoutException (iterator)
1639 
1640 template <class InputIterator>
1641 SemiFuture<std::pair<
1642  size_t,
1643  typename std::iterator_traits<InputIterator>::value_type::value_type>>
1644 collectAnyWithoutException(InputIterator first, InputIterator last) {
1645  using F = typename std::iterator_traits<InputIterator>::value_type;
1646  using T = typename F::value_type;
1647 
1648  struct Context {
1649  Context(size_t n) : nTotal(n) {}
1651  std::atomic<bool> done{false};
1652  std::atomic<size_t> nFulfilled{0};
1653  size_t nTotal;
1654  };
1655 
1656  std::vector<folly::Executor::KeepAlive<futures::detail::DeferredExecutor>>
1657  executors;
1658  futures::detail::stealDeferredExecutors(executors, first, last);
1659 
1660  auto ctx = std::make_shared<Context>(size_t(std::distance(first, last)));
1661  for (size_t i = 0; first != last; ++first, ++i) {
1662  first->setCallback_([i, ctx](Try<T>&& t) {
1663  if (!t.hasException() &&
1664  !ctx->done.exchange(true, std::memory_order_relaxed)) {
1665  ctx->p.setValue(std::make_pair(i, std::move(t.value())));
1666  } else if (
1667  ctx->nFulfilled.fetch_add(1, std::memory_order_relaxed) + 1 ==
1668  ctx->nTotal) {
1669  ctx->p.setException(t.exception());
1670  }
1671  });
1672  }
1673 
1674  auto future = ctx->p.getSemiFuture();
1675  if (!executors.empty()) {
1676  future = std::move(future).defer(
1677  [](Try<typename decltype(future)::value_type>&& t) {
1678  return std::move(t).value();
1679  });
1680  auto deferredExecutor = futures::detail::getDeferredExecutor(future);
1681  deferredExecutor->setNestedExecutors(std::move(executors));
1682  }
1683  return future;
1684 }
1685 
1686 // collectN (iterator)
1687 
1688 template <class InputIterator>
1689 SemiFuture<std::vector<std::pair<
1690  size_t,
1692 collectN(InputIterator first, InputIterator last, size_t n) {
1693  using F = typename std::iterator_traits<InputIterator>::value_type;
1694  using T = typename F::value_type;
1695  using Result = std::vector<std::pair<size_t, Try<T>>>;
1696 
1697  struct Context {
1698  explicit Context(size_t numFutures, size_t min_)
1699  : v(numFutures), min(min_) {}
1700 
1701  std::vector<Optional<Try<T>>> v;
1702  size_t min;
1703  std::atomic<size_t> completed = {0}; // # input futures completed
1704  std::atomic<size_t> stored = {0}; // # output values stored
1705  Promise<Result> p;
1706  };
1707 
1708  assert(n > 0);
1709  assert(std::distance(first, last) >= 0);
1710 
1711  if (size_t(std::distance(first, last)) < n) {
1712  return SemiFuture<Result>(
1713  exception_wrapper(std::runtime_error("Not enough futures")));
1714  }
1715 
1716  // for each completed Future, increase count and add to vector, until we
1717  // have n completed futures at which point we fulfil our Promise with the
1718  // vector
1719  auto ctx = std::make_shared<Context>(size_t(std::distance(first, last)), n);
1720  for (size_t i = 0; first != last; ++first, ++i) {
1721  first->setCallback_([i, ctx](Try<T>&& t) {
1722  // relaxed because this guards control but does not guard data
1723  auto const c = 1 + ctx->completed.fetch_add(1, std::memory_order_relaxed);
1724  if (c > ctx->min) {
1725  return;
1726  }
1727  ctx->v[i] = std::move(t);
1728 
1729  // release because the stored values in all threads must be visible below
1730  // acquire because no stored value is permitted to be fetched early
1731  auto const s = 1 + ctx->stored.fetch_add(1, std::memory_order_acq_rel);
1732  if (s < ctx->min) {
1733  return;
1734  }
1735  Result result;
1736  result.reserve(ctx->completed.load());
1737  for (size_t j = 0; j < ctx->v.size(); ++j) {
1738  auto& entry = ctx->v[j];
1739  if (entry.hasValue()) {
1740  result.emplace_back(j, std::move(entry).value());
1741  }
1742  }
1743  ctx->p.setTry(Try<Result>(std::move(result)));
1744  });
1745  }
1746 
1747  return ctx->p.getSemiFuture();
1748 }
1749 
1750 // reduce (iterator)
1751 
1752 template <class It, class T, class F>
1753 Future<T> reduce(It first, It last, T&& initial, F&& func) {
1754  if (first == last) {
1755  return makeFuture(std::forward<T>(initial));
1756  }
1757 
1758  typedef typename std::iterator_traits<It>::value_type::value_type ItT;
1759  typedef typename std::
1760  conditional<is_invocable<F, T&&, Try<ItT>&&>::value, Try<ItT>, ItT>::type
1761  Arg;
1762  typedef isTry<Arg> IsTry;
1763 
1764  auto sfunc = std::make_shared<std::decay_t<F>>(std::forward<F>(func));
1765 
1766  auto f = std::move(*first).thenTry(
1767  [initial = std::forward<T>(initial), sfunc](Try<ItT>&& head) mutable {
1768  return (*sfunc)(
1769  std::move(initial), head.template get<IsTry::value, Arg&&>());
1770  });
1771 
1772  for (++first; first != last; ++first) {
1773  f = collectAllSemiFuture(f, *first).toUnsafeFuture().thenValue(
1774  [sfunc](std::tuple<Try<T>, Try<ItT>>&& t) {
1775  return (*sfunc)(
1776  std::move(std::get<0>(t).value()),
1777  // Either return a ItT&& or a Try<ItT>&& depending
1778  // on the type of the argument of func.
1779  std::get<1>(t).template get<IsTry::value, Arg&&>());
1780  });
1781  }
1782 
1783  return f;
1784 }
1785 
1786 // window (collection)
1787 
1788 template <class Collection, class F, class ItT, class Result>
1789 std::vector<Future<Result>> window(Collection input, F func, size_t n) {
1790  // Use global QueuedImmediateExecutor singleton to avoid stack overflow.
1792  return window(executor, std::move(input), std::move(func), n);
1793 }
1794 
1795 template <class F>
1796 auto window(size_t times, F func, size_t n)
1797  -> std::vector<invoke_result_t<F, size_t>> {
1799 }
1800 
1801 template <class Collection, class F, class ItT, class Result>
1802 std::vector<Future<Result>>
1803 window(Executor* executor, Collection input, F func, size_t n) {
1804  return window(
1805  getKeepAliveToken(executor), std::move(input), std::move(func), n);
1806 }
1807 
1808 template <class Collection, class F, class ItT, class Result>
1809 std::vector<Future<Result>>
1810 window(Executor::KeepAlive<> executor, Collection input, F func, size_t n) {
1811  struct WindowContext {
1812  WindowContext(
1813  Executor::KeepAlive<> executor_,
1814  Collection&& input_,
1815  F&& func_)
1816  : executor(std::move(executor_)),
1817  input(std::move(input_)),
1818  promises(input.size()),
1819  func(std::move(func_)) {}
1820  std::atomic<size_t> i{0};
1822  Collection input;
1823  std::vector<Promise<Result>> promises;
1824  F func;
1825 
1826  static void spawn(std::shared_ptr<WindowContext> ctx) {
1827  size_t i = ctx->i.fetch_add(1, std::memory_order_relaxed);
1828  if (i < ctx->input.size()) {
1829  auto fut = makeSemiFutureWith(
1830  [&] { return ctx->func(std::move(ctx->input[i])); })
1831  .via(ctx->executor.get());
1832 
1833  fut.setCallback_([ctx = std::move(ctx), i](Try<Result>&& t) mutable {
1834  ctx->promises[i].setTry(std::move(t));
1835  // Chain another future onto this one
1836  spawn(std::move(ctx));
1837  });
1838  }
1839  }
1840  };
1841 
1842  auto max = std::min(n, input.size());
1843 
1844  auto ctx = std::make_shared<WindowContext>(
1845  executor.copy(), std::move(input), std::move(func));
1846 
1847  // Start the first n Futures
1848  for (size_t i = 0; i < max; ++i) {
1849  executor->add([ctx]() mutable { WindowContext::spawn(std::move(ctx)); });
1850  }
1851 
1852  std::vector<Future<Result>> futures;
1853  futures.reserve(ctx->promises.size());
1854  for (auto& promise : ctx->promises) {
1855  futures.emplace_back(promise.getSemiFuture().via(executor.copy()));
1856  }
1857 
1858  return futures;
1859 }
1860 
1861 // reduce
1862 
1863 template <class T>
1864 template <class I, class F>
1865 Future<I> Future<T>::reduce(I&& initial, F&& func) && {
1866  return std::move(*this).thenValue(
1867  [minitial = std::forward<I>(initial),
1868  mfunc = std::forward<F>(func)](T&& vals) mutable {
1869  auto ret = std::move(minitial);
1870  for (auto& val : vals) {
1871  ret = mfunc(std::move(ret), std::move(val));
1872  }
1873  return ret;
1874  });
1875 }
1876 
1877 // unorderedReduce (iterator)
1878 
1879 // TODO(T26439406): Make return SemiFuture
1880 template <class It, class T, class F>
1881 Future<T> unorderedReduce(It first, It last, T initial, F func) {
1882  using ItF = typename std::iterator_traits<It>::value_type;
1883  using ItT = typename ItF::value_type;
1884  using Arg = MaybeTryArg<F, T, ItT>;
1885 
1886  if (first == last) {
1887  return makeFuture(std::move(initial));
1888  }
1889 
1890  typedef isTry<Arg> IsTry;
1891 
1892  struct Context {
1893  Context(T&& memo, F&& fn, size_t n)
1894  : lock_(),
1895  memo_(makeFuture<T>(std::move(memo))),
1896  func_(std::move(fn)),
1897  numThens_(0),
1898  numFutures_(n),
1899  promise_() {}
1900 
1901  folly::MicroSpinLock lock_; // protects memo_ and numThens_
1902  Future<T> memo_;
1903  F func_;
1904  size_t numThens_; // how many Futures completed and called .then()
1905  size_t numFutures_; // how many Futures in total
1907  };
1908 
1909  struct Fulfill {
1910  void operator()(Promise<T>&& p, T&& v) const {
1911  p.setValue(std::move(v));
1912  }
1913  void operator()(Promise<T>&& p, Future<T>&& f) const {
1914  f.setCallback_(
1915  [p = std::move(p)](Try<T>&& t) mutable { p.setTry(std::move(t)); });
1916  }
1917  };
1918 
1919  auto ctx = std::make_shared<Context>(
1920  std::move(initial), std::move(func), std::distance(first, last));
1921  for (size_t i = 0; first != last; ++first, ++i) {
1922  first->setCallback_([i, ctx](Try<ItT>&& t) {
1923  (void)i;
1924  // Futures can be completed in any order, simultaneously.
1925  // To make this non-blocking, we create a new Future chain in
1926  // the order of completion to reduce the values.
1927  // The spinlock just protects chaining a new Future, not actually
1928  // executing the reduce, which should be really fast.
1929  Promise<T> p;
1930  auto f = p.getFuture();
1931  {
1932  folly::MSLGuard lock(ctx->lock_);
1933  f = exchange(ctx->memo_, std::move(f));
1934  if (++ctx->numThens_ == ctx->numFutures_) {
1935  // After reducing the value of the last Future, fulfill the Promise
1936  ctx->memo_.setCallback_(
1937  [ctx](Try<T>&& t2) { ctx->promise_.setValue(std::move(t2)); });
1938  }
1939  }
1940  f.setCallback_(
1941  [ctx, mp = std::move(p), mt = std::move(t)](Try<T>&& v) mutable {
1942  if (v.hasValue()) {
1943  try {
1944  Fulfill{}(
1945  std::move(mp),
1946  ctx->func_(
1947  std::move(v.value()),
1948  mt.template get<IsTry::value, Arg&&>()));
1949  } catch (std::exception& e) {
1950  mp.setException(exception_wrapper(std::current_exception(), e));
1951  } catch (...) {
1952  mp.setException(exception_wrapper(std::current_exception()));
1953  }
1954  } else {
1955  mp.setTry(std::move(v));
1956  }
1957  });
1958  });
1959  }
1960  return ctx->promise_.getSemiFuture().via(&InlineExecutor::instance());
1961 }
1962 
1963 // within
1964 
1965 template <class T>
1967  return std::move(*this).within(dur, FutureTimeout(), tk);
1968 }
1969 
1970 template <class T>
1971 template <class E>
1973  if (this->isReady()) {
1974  return std::move(*this);
1975  }
1976 
1977  auto* exe = this->getExecutor();
1978  return std::move(*this)
1979  .withinImplementation(dur, e, tk)
1980  .via(exe ? exe : &InlineExecutor::instance());
1981 }
1982 
1983 // delayed
1984 
1985 template <class T>
1987  auto e = this->getExecutor();
1988  return collectAllSemiFuture(*this, futures::sleep(dur, tk))
1989  .via(e ? e : &InlineExecutor::instance())
1990  .thenValue([](std::tuple<Try<T>, Try<Unit>>&& tup) {
1991  return makeFuture<T>(std::get<0>(std::move(tup)));
1992  });
1993 }
1994 
1995 template <class T>
1997  return std::move(*this).semi().delayed(dur, tk).toUnsafeFuture();
1998 }
1999 
2000 namespace futures {
2001 namespace detail {
2002 
2003 template <class FutureType, typename T = typename FutureType::value_type>
2004 void waitImpl(FutureType& f) {
2005  if (std::is_base_of<Future<T>, FutureType>::value) {
2006  f = std::move(f).via(&InlineExecutor::instance());
2007  }
2008  // short-circuit if there's nothing to do
2009  if (f.isReady()) {
2010  return;
2011  }
2012 
2013  Promise<T> promise;
2014  auto ret = promise.getSemiFuture();
2015  auto baton = std::make_shared<FutureBatonType>();
2016  f.setCallback_([baton, promise = std::move(promise)](Try<T>&& t) mutable {
2017  promise.setTry(std::move(t));
2018  baton->post();
2019  });
2020  convertFuture(std::move(ret), f);
2021  baton->wait();
2022  assert(f.isReady());
2023 }
2024 
2025 template <class T>
2027  // Carry executor from f, inserting an inline executor if it did not have one
2028  auto* exe = f.getExecutor();
2029  f = std::move(sf).via(exe ? exe : &InlineExecutor::instance());
2030 }
2031 
2032 template <class T>
2034  f = std::move(sf);
2035 }
2036 
2037 template <class FutureType, typename T = typename FutureType::value_type>
2038 void waitImpl(FutureType& f, Duration dur) {
2039  if (std::is_base_of<Future<T>, FutureType>::value) {
2040  f = std::move(f).via(&InlineExecutor::instance());
2041  }
2042  // short-circuit if there's nothing to do
2043  if (f.isReady()) {
2044  return;
2045  }
2046 
2047  Promise<T> promise;
2048  auto ret = promise.getSemiFuture();
2049  auto baton = std::make_shared<FutureBatonType>();
2050  f.setCallback_([baton, promise = std::move(promise)](Try<T>&& t) mutable {
2051  promise.setTry(std::move(t));
2052  baton->post();
2053  });
2054  convertFuture(std::move(ret), f);
2055  if (baton->try_wait_for(dur)) {
2056  assert(f.isReady());
2057  }
2058 }
2059 
2060 template <class T>
2062  // Set callback so to ensure that the via executor has something on it
2063  // so that once the preceding future triggers this callback, drive will
2064  // always have a callback to satisfy it
2065  if (f.isReady()) {
2066  return;
2067  }
2068  f = std::move(f).via(e).thenValue([](T&& t) { return std::move(t); });
2069  while (!f.isReady()) {
2070  e->drive();
2071  }
2072  assert(f.isReady());
2073  f = std::move(f).via(&InlineExecutor::instance());
2074 }
2075 
2076 template <class T, typename Rep, typename Period>
2078  Future<T>& f,
2080  const std::chrono::duration<Rep, Period>& timeout) {
2081  // Set callback so to ensure that the via executor has something on it
2082  // so that once the preceding future triggers this callback, drive will
2083  // always have a callback to satisfy it
2084  if (f.isReady()) {
2085  return;
2086  }
2087  // Chain operations, ensuring that the executor is kept alive for the duration
2088  f = std::move(f).via(e).thenValue(
2089  [keepAlive = getKeepAliveToken(e)](T&& t) { return std::move(t); });
2091  auto deadline = now + timeout;
2092  while (!f.isReady() && (now < deadline)) {
2093  e->try_drive_until(deadline);
2095  }
2096  assert(f.isReady() || (now >= deadline));
2097  if (f.isReady()) {
2098  f = std::move(f).via(&InlineExecutor::instance());
2099  }
2100 }
2101 
2102 } // namespace detail
2103 } // namespace futures
2104 
2105 template <class T>
2107  if (auto deferredExecutor = getDeferredExecutor()) {
2108  // Make sure that the last callback in the future chain will be run on the
2109  // WaitExecutor.
2110  Promise<T> promise;
2111  auto ret = promise.getSemiFuture();
2112  setCallback_(
2113  [p = std::move(promise)](auto&& r) mutable { p.setTry(std::move(r)); });
2114  auto waitExecutor = futures::detail::WaitExecutor::create();
2115  deferredExecutor->setExecutor(waitExecutor.copy());
2116  while (!ret.isReady()) {
2117  waitExecutor->drive();
2118  }
2119  waitExecutor->detach();
2120  this->detach();
2121  *this = std::move(ret);
2122  } else {
2124  }
2125  return *this;
2126 }
2127 
2128 template <class T>
2130  return std::move(wait());
2131 }
2132 
2133 template <class T>
2135  if (auto deferredExecutor = getDeferredExecutor()) {
2136  // Make sure that the last callback in the future chain will be run on the
2137  // WaitExecutor.
2138  Promise<T> promise;
2139  auto ret = promise.getSemiFuture();
2140  setCallback_(
2141  [p = std::move(promise)](auto&& r) mutable { p.setTry(std::move(r)); });
2142  auto waitExecutor = futures::detail::WaitExecutor::create();
2143  auto deadline = futures::detail::WaitExecutor::Clock::now() + dur;
2144  deferredExecutor->setExecutor(waitExecutor.copy());
2145  while (!ret.isReady()) {
2146  if (!waitExecutor->driveUntil(deadline)) {
2147  break;
2148  }
2149  }
2150  waitExecutor->detach();
2151  this->detach();
2152  *this = std::move(ret);
2153  } else {
2154  futures::detail::waitImpl(*this, dur);
2155  }
2156  return *this;
2157 }
2158 
2159 template <class T>
2160 bool SemiFuture<T>::wait(Duration dur) && {
2161  auto future = std::move(*this);
2162  future.wait(dur);
2163  return future.isReady();
2164 }
2165 
2166 template <class T>
2168  return std::move(*this).getTry().value();
2169 }
2170 
2171 template <class T>
2173  return std::move(*this).getTry(dur).value();
2174 }
2175 
2176 template <class T>
2178  wait();
2179  auto future = folly::Future<T>(this->core_);
2180  this->core_ = nullptr;
2181  return std::move(std::move(future).getTry());
2182 }
2183 
2184 template <class T>
2186  wait(dur);
2187  auto future = folly::Future<T>(this->core_);
2188  this->core_ = nullptr;
2189 
2190  if (!future.isReady()) {
2191  throw_exception<FutureTimeout>();
2192  }
2193  return std::move(std::move(future).getTry());
2194 }
2195 
2196 template <class T>
2199  return *this;
2200 }
2201 
2202 template <class T>
2203 Future<T>&& Future<T>::wait() && {
2205  return std::move(*this);
2206 }
2207 
2208 template <class T>
2210  futures::detail::waitImpl(*this, dur);
2211  return *this;
2212 }
2213 
2214 template <class T>
2216  futures::detail::waitImpl(*this, dur);
2217  return std::move(*this);
2218 }
2219 
2220 template <class T>
2222  futures::detail::waitViaImpl(*this, e);
2223  return *this;
2224 }
2225 
2226 template <class T>
2228  futures::detail::waitViaImpl(*this, e);
2229  return std::move(*this);
2230 }
2231 
2232 template <class T>
2234  futures::detail::waitViaImpl(*this, e, dur);
2235  return *this;
2236 }
2237 
2238 template <class T>
2240  futures::detail::waitViaImpl(*this, e, dur);
2241  return std::move(*this);
2242 }
2243 
2244 template <class T>
2246  wait();
2247  return copy(std::move(*this)).value();
2248 }
2249 
2250 template <class T>
2252  wait(dur);
2253  auto future = copy(std::move(*this));
2254  if (!future.isReady()) {
2255  throw_exception<FutureTimeout>();
2256  }
2257  return std::move(future).value();
2258 }
2259 
2260 template <class T>
2262  return result();
2263 }
2264 
2265 template <class T>
2267  return std::move(waitVia(e).value());
2268 }
2269 
2270 template <class T>
2272  waitVia(e, dur);
2273  if (!this->isReady()) {
2274  throw_exception<FutureTimeout>();
2275  }
2276  return std::move(value());
2277 }
2278 
2279 template <class T>
2281  return waitVia(e).getTry();
2282 }
2283 
2284 template <class T>
2286  waitVia(e, dur);
2287  if (!this->isReady()) {
2288  throw_exception<FutureTimeout>();
2289  }
2290  return result();
2291 }
2292 
2293 namespace futures {
2294 namespace detail {
2295 template <class T>
2296 struct TryEquals {
2297  static bool equals(const Try<T>& t1, const Try<T>& t2) {
2298  return t1.value() == t2.value();
2299  }
2300 };
2301 } // namespace detail
2302 } // namespace futures
2303 
2304 template <class T>
2306  return collectAllSemiFuture(*this, f).toUnsafeFuture().thenValue(
2307  [](const std::tuple<Try<T>, Try<T>>& t) {
2308  if (std::get<0>(t).hasValue() && std::get<1>(t).hasValue()) {
2310  std::get<0>(t), std::get<1>(t));
2311  } else {
2312  return false;
2313  }
2314  });
2315 }
2316 
2317 template <class T>
2318 template <class F>
2319 Future<T> Future<T>::filter(F&& predicate) && {
2320  return std::move(*this).thenValue([p = std::forward<F>(predicate)](T val) {
2321  T const& valConstRef = val;
2322  if (!p(valConstRef)) {
2323  throw_exception<FuturePredicateDoesNotObtain>();
2324  }
2325  return val;
2326  });
2327 }
2328 
2329 template <class F>
2330 Future<Unit> when(bool p, F&& thunk) {
2331  return p ? std::forward<F>(thunk)().unit() : makeFuture();
2332 }
2333 
2334 template <class P, class F>
2335 Future<Unit> whileDo(P&& predicate, F&& thunk) {
2336  if (predicate()) {
2337  auto future = thunk();
2338  return std::move(future).thenValue(
2339  [predicate = std::forward<P>(predicate),
2340  thunk = std::forward<F>(thunk)](auto&&) mutable {
2341  return whileDo(std::forward<P>(predicate), std::forward<F>(thunk));
2342  });
2343  }
2344  return makeFuture();
2345 }
2346 
2347 template <class F>
2348 Future<Unit> times(const int n, F&& thunk) {
2349  return folly::whileDo(
2350  [n, count = std::make_unique<std::atomic<int>>(0)]() mutable {
2351  return count->fetch_add(1, std::memory_order_relaxed) < n;
2352  },
2353  std::forward<F>(thunk));
2354 }
2355 
2356 namespace futures {
2357 template <class It, class F, class ItT, class Result>
2358 std::vector<Future<Result>> map(It first, It last, F func) {
2359  std::vector<Future<Result>> results;
2360  results.reserve(std::distance(first, last));
2361  for (auto it = first; it != last; it++) {
2363  FOLLY_GNU_DISABLE_WARNING("-Wdeprecated-declarations")
2364  results.push_back(std::move(*it).then(func));
2366  }
2367  return results;
2368 }
2369 
2370 template <class It, class F, class ItT, class Result>
2371 std::vector<Future<Result>> map(Executor& exec, It first, It last, F func) {
2372  std::vector<Future<Result>> results;
2373  results.reserve(std::distance(first, last));
2374  for (auto it = first; it != last; it++) {
2376  FOLLY_GNU_DISABLE_WARNING("-Wdeprecated-declarations")
2377  results.push_back(std::move(*it).via(&exec).then(func));
2379  }
2380  return results;
2381 }
2382 
2383 } // namespace futures
2384 
2385 template <class Clock>
2386 Future<Unit> Timekeeper::at(std::chrono::time_point<Clock> when) {
2387  auto now = Clock::now();
2388 
2389  if (when <= now) {
2390  return makeFuture();
2391  }
2392 
2393  return after(std::chrono::duration_cast<Duration>(when - now));
2394 }
2395 
2396 // Instantiate the most common Future types to save compile time
2397 extern template class Future<Unit>;
2398 extern template class Future<bool>;
2399 extern template class Future<int>;
2400 extern template class Future<int64_t>;
2401 extern template class Future<std::string>;
2402 extern template class Future<double>;
2403 } // namespace folly
folly::fibers::Baton FutureBatonType
Definition: Future-inl.h:45
void setException(exception_wrapper &&ew)
Definition: Future-inl.h:103
Future< T > via(Executor *executor, int8_t priority=Executor::MID_PRI)&&
Definition: Future-inl.h:1024
Definition: InvokeTest.cpp:58
Future & operator=(Future< T2 > &&)
Future< T > within(Duration dur, Timekeeper *tk=nullptr)&&
Definition: Future-inl.h:1966
make_index_sequence< sizeof...(T)> index_sequence_for
Definition: Utility.h:211
void raise(exception_wrapper e)
Definition: Core.h:453
void waitImpl(FutureType &f)
Definition: Future-inl.h:2004
#define FOLLY_GNU_DISABLE_WARNING(warningName)
Definition: Portability.h:180
Future< T > thenError(F &&func)&&
Definition: Future-inl.h:1092
#define FOLLY_POP_WARNING
Definition: Portability.h:179
bool try_drive_until(const std::chrono::time_point< Clock, Duration > &deadline) noexcept
auto f
decltype(auto) invoke(R, State &state, Try< T > &)
Definition: Future-inl.h:285
friend Future< T2 > makeFuture(Try< T2 >)
Future< Unit > whileDo(P &&predicate, F &&thunk)
Definition: Future-inl.h:2335
static SemiFuture< T > makeEmpty()
Definition: Future-inl.h:775
auto v
static QueuedImmediateExecutor & instance()
typename invoke_result< F, Args... >::type invoke_result_t
Definition: Invoke.h:142
std::shared_ptr< Timekeeper > getTimekeeperSingleton()
#define FOLLY_PUSH_WARNING
Definition: Portability.h:178
#define FOLLY_ALWAYS_INLINE
Definition: CPortability.h:151
LogLevel max
Definition: LogLevel.cpp:31
friend Future< Unit > when(bool p, F &&thunk)
Definition: Future-inl.h:2330
CoreCallbackState(CoreCallbackState &&that) noexcept(noexcept(DF(std::declval< F && >())))
Definition: Future-inl.h:71
static Promise< T > makeEmpty() noexcept
Definition: Promise-inl.h:40
PskType type
Future< Unit > then()&&
Definition: Future-inl.h:1120
Future< I > reduce(I &&initial, F &&func)&&
Definition: Future-inl.h:1865
CoreCallbackState(Promise< T > &&promise, F &&func) noexcept(noexcept(DF(std::declval< F && >())))
Definition: Future-inl.h:65
Future< Unit > sleep(Duration dur, Timekeeper *tk)
Definition: Future.cpp:42
void setExecutor(folly::Executor::KeepAlive<> executor)
Definition: Future-inl.h:525
Executor * getExecutor() const
Definition: Future.h:412
std::chrono::steady_clock::time_point now()
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static void releaseDeferredExecutor(Core *core)
Definition: Future-inl.h:803
static KeepAlive< DeferredExecutor > create()
Definition: Future-inl.h:578
#define LIKELY(x)
Definition: Likely.h:47
std::lock_guard< MicroSpinLock > MSLGuard
STL namespace.
std::integral_constant< std::size_t, I > index_constant
Definition: Traits.h:150
auto makeCoreCallbackState(Promise< T > &&p, F &&f) noexcept(noexcept(CoreCallbackState< T, F >(std::declval< Promise< T > && >(), std::declval< F && >())))
Definition: Future-inl.h:125
double val
Definition: String.cpp:273
std::vector< size_t >::iterator iterator
Definition: Future-inl.h:694
Future< T > unorderedReduce(It first, It last, T initial, F func)
Definition: Future-inl.h:1881
SemiFuture< std::tuple< Try< typename remove_cvref_t< Fs >::value_type >... > > collectAllSemiFuture(Fs &&...fs)
Definition: Future-inl.h:1441
folly::std T
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
exception_wrapper & exception()&
Definition: Try.h:260
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
std::unique_ptr< std::vector< folly::Executor::KeepAlive< DeferredExecutor > > > nestedExecutors_
Definition: Future-inl.h:606
in_place_tag in_place(in_place_tag={})
Definition: Utility.h:235
requires E e noexcept(noexcept(s.error(std::move(e))))
in_place_tag(&)(in_place_tag) in_place_t
Definition: Utility.h:229
PUSHMI_INLINE_VAR constexpr detail::transform_fn transform
Definition: transform.h:158
const int min_
void setNestedExecutors(std::vector< folly::Executor::KeepAlive< DeferredExecutor >> executors)
Definition: Future-inl.h:570
SemiFuture< std::vector< std::pair< size_t, Try< typename std::iterator_traits< InputIterator >::value_type::value_type > > > > collectN(InputIterator first, InputIterator last, size_t n)
Definition: Future-inl.h:1692
Try< T > & getTryVia(DrivableExecutor *e)
Definition: Future-inl.h:2280
friend Future< Unit > times(int n, F &&thunk)
Definition: Future-inl.h:2348
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
void setTry(Try< T > &&t)
Definition: Promise-inl.h:122
typename lift_unit< T >::type Inner
Definition: Future-pre.h:40
Future< T > via(Executor *executor, int8_t priority=Executor::MID_PRI)&&
Returns a Future which will call back on the other side of executor.
Definition: Future-inl.h:870
void detachFuture() noexcept
Definition: Core.h:409
std::vector< Future< Result > > window(Collection input, F func, size_t n)
Definition: Future-inl.h:1789
Future< T > & wait()&
Definition: Future-inl.h:2197
Future< bool > willEqual(Future< T > &)
Definition: Future-inl.h:2305
DeferredExecutor * getDeferredExecutor(SemiFuture< T > &future)
Definition: Future-inl.h:1395
SemiFuture< std::pair< size_t, typename std::iterator_traits< InputIterator >::value_type::value_type > > collectAnyWithoutException(InputIterator first, InputIterator last)
Definition: Future-inl.h:1644
std::enable_if< isFutureOrSemiFuture< invoke_result_t< F > >::value, SemiFuture< typename invoke_result_t< F >::value_type > >::type makeSemiFutureWith(F &&func)
Definition: Future-inl.h:721
Future< T > onTimeout(Duration, F &&func, Timekeeper *=nullptr)&&
Definition: Future-inl.h:1213
constexpr std::decay< T >::type copy(T &&value) noexcept(noexcept(typename std::decay< T >::type(std::forward< T >(value))))
Definition: Utility.h:72
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
void raise(exception_wrapper interrupt)
Definition: Future-inl.h:262
bool hasException() const
Definition: Try.h:248
std::enable_if_t< R::Arg::ArgsSize::value==S, int > IfArgsSizeIs
Definition: Future-inl.h:283
static std::shared_ptr< RequestContext > saveContext()
Definition: Request.h:196
std::weak_ptr< T > to_weak_ptr(const std::shared_ptr< T > &ptr)
Definition: Memory.h:346
std::chrono::milliseconds Duration
Definition: Types.h:36
State
See Core for details.
Definition: Core.h:43
constexpr auto empty(C const &c) -> decltype(c.empty())
Definition: Access.h:55
LogLevel min
Definition: LogLevel.cpp:30
void waitViaImpl(Future< T > &f, TimedDrivableExecutor *e, const std::chrono::duration< Rep, Period > &timeout)
Definition: Future-inl.h:2077
typename lift_unit< T >::type lift_unit_t
Definition: Unit.h:56
Future< T > delayed(Duration, Timekeeper *=nullptr)&&
Definition: Future-inl.h:1986
constexpr auto invoke(F &&f, Args &&...args) noexcept(noexcept(static_cast< F && >(f)(static_cast< Args && >(args)...))) -> decltype(static_cast< F && >(f)(static_cast< Args && >(args)...))
Definition: Invoke.h:49
Future< T > filter(F &&predicate)&&
Definition: Future-inl.h:2319
Future< typename futures::detail::tryCallableResult< T, F >::value_type > thenTry(F &&func)&&
Definition: Future-inl.h:1068
PolymorphicAction< internal::InvokeAction< FunctionImpl > > Invoke(FunctionImpl function_impl)
SemiFuture< T > deferError(F &&func)&&
Definition: Future-inl.h:913
DeferredExecutor * getDeferredExecutor() const
Definition: Future-inl.h:780
typename T::type _t
Definition: Traits.h:171
Future< std::pair< size_t, Try< typename std::iterator_traits< InputIterator >::value_type::value_type > > > collectAny(InputIterator first, InputIterator last)
Definition: Future-inl.h:1618
SemiFuture< T > & wait()&
Definition: Future-inl.h:2106
std::enable_if<!R::ReturnsFuture::value, typename R::Return >::type thenImplementation(F &&func, R)
Definition: Future-inl.h:311
Future< T > & waitVia(DrivableExecutor *e)&
Definition: Future-inl.h:2221
SemiFuture< T > delayed(Duration dur, Timekeeper *tk=nullptr)&&
Definition: Future-inl.h:941
void waitImpl(FutureType &f, Duration dur)
Definition: Future-inl.h:2038
Core * core_
Definition: Promise.h:438
static Map map(mapCap)
Try< T > getTry()&&
Definition: Future-inl.h:2177
FOLLY_ATTR_VISIBILITY_HIDDEN static FOLLY_ALWAYS_INLINE InlineExecutor & instance() noexcept
auto lock(Synchronized< D, M > &synchronized, Args &&...args)
Future< T > getFuture()
Definition: Promise-inl.h:97
void convertFuture(SemiFuture< T > &&sf, SemiFuture< T > &f)
Definition: Future-inl.h:2033
Promise< Unit > promise_
auto invoke(Args &&...args) noexcept(noexcept(std::declval< F && >()(std::declval< Args && >()...)))
Definition: Future-inl.h:88
Future< T > delayedUnsafe(Duration, Timekeeper *=nullptr)
Definition: Future-inl.h:1996
Future< std::tuple< Try< typename remove_cvref_t< Fs >::value_type >... > > collectAll(Fs &&...fs)
Definition: Future-inl.h:1477
constexpr Unit unit
Definition: Unit.h:45
SemiFuture< typename futures::detail::tryCallableResult< T, F >::value_type > defer(F &&func)&&
Definition: Future-inl.h:882
Future< T > chainExecutor(Executor *, Future< T > &&f)
Definition: Future-inl.h:370
bool driveUntil(Clock::time_point deadline)
Definition: Future-inl.h:635
static bool equals(const Try< T > &t1, const Try< T > &t2)
Definition: Future-inl.h:2297
bool hasCallback() const noexcept
May call from any thread.
Definition: Core.h:231
friend Future< Unit > whileDo(P &&predicate, F &&thunk)
Definition: Future-inl.h:2335
void setExecutor(Executor::KeepAlive<> x, int8_t priority=Executor::MID_PRI)
Definition: Core.h:424
static const char *const value
Definition: Conv.cpp:50
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&...args)
Definition: Memory.h:259
std::enable_if< isFuture< F >::value, Future< typename isFuture< T >::Inner > >::type unwrap()&&
Definition: Future-inl.h:1007
void waitViaImpl(Future< T > &f, DrivableExecutor *e)
Definition: Future-inl.h:2061
SemiFuture< typename futures::detail::valueCallableResult< T, F >::value_type > deferValue(F &&func)&&
Definition: Future-inl.h:901
Definition: Try.h:51
void assign(FutureBase< T > &&other) noexcept
Definition: Future-inl.h:167
folly::Executor::KeepAlive executor_
Definition: Future-inl.h:604
std::chrono::steady_clock Clock
Definition: Future-inl.h:633
int * count
Try< T > & getTry()
Definition: Future-inl.h:2261
Executor * getExecutor() const
Definition: Core.h:436
SemiFuture< T > getSemiFuture()
Definition: Promise-inl.h:88
Future< std::vector< typename std::iterator_traits< InputIterator >::value_type::value_type > > collect(InputIterator first, InputIterator last)
Definition: Future-inl.h:1536
void setExecutor(Executor *x, int8_t priority=Executor::MID_PRI)
Definition: Future.h:420
folly::Executor::KeepAlive< DeferredExecutor > stealDeferredExecutor() const
Definition: Future-inl.h:791
T exchange(T &obj, U &&new_value)
Definition: Utility.h:120
KeepAlive copy() const
Definition: Executor.h:113
std::enable_if< !std::is_same< invoke_result_t< F >, void >::value, Try< invoke_result_t< F > > >::type makeTryWith(F &&f)
Definition: Try-inl.h:223
SemiFuture< T > withinImplementation(Duration dur, E e, Timekeeper *tk)&&
Definition: Future-inl.h:430
typename std::conditional< is_invocable< F, T &&, Try< ItT > && >::value, Try< ItT >, ItT >::type MaybeTryArg
Definition: helpers.h:445
void stealDeferredExecutors(std::vector< folly::Executor::KeepAlive< DeferredExecutor >> &executors, InputIterator first, InputIterator last)
Definition: Future-inl.h:1424
Future< T > toUnsafeFuture()&&
Definition: Future-inl.h:875
static set< string > s
const
Definition: upload.py:398
friend class SemiFuture
Definition: Future.h:883
void setInterruptHandlerNoLock(std::function< void(exception_wrapper const &)> fn)
Definition: Core.h:494
void setCallback(F &&func, std::shared_ptr< folly::RequestContext > context)
Definition: Core.h:306
Future< Unit > at(std::chrono::time_point< Clock > when)
Definition: Future-inl.h:2386
const internal::AnythingMatcher _
T & value()&
Definition: Try-inl.h:140
InlineExecutor exe
Definition: Benchmark.cpp:337
Executor::KeepAlive< ExecutorT > getKeepAliveToken(ExecutorT *executor)
Definition: Executor.h:200
T getVia(DrivableExecutor *e)
Definition: Future-inl.h:2266
folly::Synchronized< Queue > queue_
Definition: Future-inl.h:684
Future< T > ensure(F &&func)&&
Definition: Future-inl.h:1203
virtual void drive()=0
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN void foreach(V &&v, Fs &&...fs)
Definition: Future-inl.h:1387
#define UNLIKELY(x)
Definition: Likely.h:48
#define FOLLY_ATTR_VISIBILITY_HIDDEN
Definition: CPortability.h:160
friend class Future
Definition: Future.h:1933
std::enable_if< !is_invocable< F, exception_wrapper >::value &&!futures::detail::Extract< F >::ReturnsFuture::value, Future< T > >::type onError(F &&func)&&
Definition: Future-inl.h:1131
PUSHMI_INLINE_VAR constexpr detail::get_fn< T > get
Definition: submit.h:391
FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN void foreach_(index_sequence< Is... >, V &&v, Fs &&...fs)
Definition: Future-inl.h:1382
decltype(auto) tryInvoke(R, State &state, Try< T > &)
Definition: Future-inl.h:294
char c
void add(Func func) override
Definition: Future-inl.h:612
Future< typename futures::detail::valueCallableResult< T, F >::value_type > thenValue(F &&func)&&
Definition: Future-inl.h:1079
void stealDeferredExecutorsVariadic(std::vector< folly::Executor::KeepAlive< DeferredExecutor >> &executors, Ts &...ts)
Definition: Future-inl.h:1411
bool hasResult() const noexcept
Definition: Core.h:242
folly::Executor::KeepAlive< DeferredExecutor > stealDeferredExecutor(Future< T > &)
Definition: Future-inl.h:1406
auto unwrapTryTuple(Tuple &&instance)
Definition: Try-inl.h:320
auto tryInvoke(Args &&...args) noexcept
Definition: Future-inl.h:95
static KeepAlive< WaitExecutor > create()
Definition: Future-inl.h:656
Optional< Try< T > > poll()
Definition: Future-inl.h:255
Promise< T > stealPromise() noexcept
Definition: Future-inl.h:107
state
Definition: http_parser.c:272
size_t operator[](const size_t index) const
Definition: Future-inl.h:698
std::enable_if< isFuture< invoke_result_t< F > >::value, invoke_result_t< F > >::type makeFutureWith(F &&func)
Definition: Future-inl.h:1322
static Future< T > makeEmpty()
Definition: Future-inl.h:951
SemiFuture< typename std::decay< T >::type > makeSemiFuture(T &&t)
Definition: Future-inl.h:712
SemiFuture & operator=(SemiFuture const &)=delete
constexpr detail::First first
Definition: Base-inl.h:2553
#define B(name, bit)
Definition: CpuId.h:178
static Core * make()
State will be Start.
Definition: Core.h:205