mirror of
https://github.com/clearlinux/folly.git
synced 2026-09-01 11:15:52 +00:00
then-with-Executor
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 Reviewed By: jsedgwick@fb.com Subscribers: robbert, exa, folly-diffs@, jsedgwick, nkgupta, yfeldblum, chalfant, davejwatson FB internal diff: D1985475 Signature: t1:1985475:1429148056:0450120263ba8110e8825420cbefe3b1887f7306
This commit is contained in:
@@ -235,6 +235,16 @@ Future<T>::then(R(Caller::*func)(Args...), Caller *instance) {
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Future<void> Future<T>::then() {
|
||||
return then([] (Try<T>&& t) {});
|
||||
|
||||
@@ -325,6 +325,22 @@ class Future {
|
||||
Future<typename isFuture<R>::Inner>
|
||||
then(R(Caller::*func)(Args...), Caller *instance);
|
||||
|
||||
/// 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)...));
|
||||
|
||||
/// Convenience method for ignoring the value and creating a Future<void>.
|
||||
/// Exceptions still propagate.
|
||||
Future<void> then();
|
||||
|
||||
@@ -184,3 +184,33 @@ TEST(Via, chain3) {
|
||||
EXPECT_EQ(42, f.get());
|
||||
EXPECT_EQ(3, count);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user