Summary:
Pass an Executor to `then`, which applies only for that callback. This is on
the one hand just a convenience method, but it's a major convenience when it's
needed, because grabbing, storing, and restoring the old Executor in the
middle of a chain is very inconvenient indeed.
Test Plan:
new unit
docblock comments
Reviewed By: jsedgwick@fb.com
Subscribers: folly-diffs@, davejwatson, chalfant, yfeldblum, nkgupta, jsedgwick, exa, robbert
FB internal diff:
D2011542
Tasks:
6771589,
6838553
Signature: t1:
2011542:
1429660204:
f5959b1e0b3b36dfb8c3c7091302d19101dde93b
});
}
+// TODO(6838553)
+#ifndef __clang__
+template <class T>
+template <class... Args>
+auto Future<T>::then(Executor* x, Args&&... args)
+ -> decltype(this->then(std::forward<Args>(args)...))
+{
+ auto oldX = getExecutor();
+ setExecutor(x);
+ return this->then(std::forward<Args>(args)...).via(oldX);
+}
+#endif
+
template <class T>
Future<void> Future<T>::then() {
return then([] (Try<T>&& t) {});
Future<typename isFuture<R>::Inner>
then(R(Caller::*func)(Args...), Caller *instance);
+// TODO(6838553)
+#ifndef __clang__
+ /// Execute the callback via the given Executor. The executor doesn't stick.
+ ///
+ /// Contrast
+ ///
+ /// f.via(x).then(b).then(c)
+ ///
+ /// with
+ ///
+ /// f.then(x, b).then(c)
+ ///
+ /// In the former both b and c execute via x. In the latter, only b executes
+ /// via x, and c executes via the same executor (if any) that f had.
+ template <class... Args>
+ auto then(Executor* x, Args&&... args)
+ -> decltype(this->then(std::forward<Args>(args)...));
+#endif
+
/// Convenience method for ignoring the value and creating a Future<void>.
/// Exceptions still propagate.
Future<void> then();
EXPECT_EQ(42, f.get());
EXPECT_EQ(3, count);
}
+
+// TODO(6838553)
+#ifndef __clang__
+TEST(Via, then2) {
+ ManualExecutor x1, x2;
+ bool a,b,c;
+ via(&x1)
+ .then([&]{ a = true; })
+ .then(&x2, [&]{ b = true; })
+ .then([&]{ c = true; });
+
+ EXPECT_FALSE(a);
+ EXPECT_FALSE(b);
+
+ x1.run();
+ EXPECT_TRUE(a);
+ EXPECT_FALSE(b);
+ EXPECT_FALSE(c);
+
+ x2.run();
+ EXPECT_TRUE(b);
+ EXPECT_FALSE(c);
+
+ x1.run();
+ EXPECT_TRUE(c);
+}
+
+TEST(Via, then2Variadic) {
+ struct Foo { void foo(Try<void>) {} };
+ Foo f;
+ makeFuture().then(nullptr, &Foo::foo, &f);
+}
+#endif