From 8bed062637f2af0e85fb5fd4365476e28e18d078 Mon Sep 17 00:00:00 2001 From: Phil Willoughby Date: Mon, 26 Sep 2016 04:59:05 -0700 Subject: [PATCH] Make a SharedPromise from a Future Summary: Makes it easy to split a Future into multiple Futures Reviewed By: rongrong Differential Revision: D3885897 fbshipit-source-id: 6ac9fb22444dd828fbdebb44b06bf3d93d0f7583 --- folly/futures/SharedPromise-inl.h | 5 ++++ folly/futures/SharedPromise.h | 7 ++++++ folly/futures/test/SharedPromiseTest.cpp | 30 ++++++++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/folly/futures/SharedPromise-inl.h b/folly/futures/SharedPromise-inl.h index 90d0dd3d..490e0864 100644 --- a/folly/futures/SharedPromise-inl.h +++ b/folly/futures/SharedPromise-inl.h @@ -47,6 +47,11 @@ SharedPromise& SharedPromise::operator=( return *this; } +template +SharedPromise::SharedPromise(Future future) { + future.then(&SharedPromise::setTry, this); +} + template size_t SharedPromise::size() { std::lock_guard g(mutex_); diff --git a/folly/futures/SharedPromise.h b/folly/futures/SharedPromise.h index cdc284dd..d1f8a949 100644 --- a/folly/futures/SharedPromise.h +++ b/folly/futures/SharedPromise.h @@ -46,6 +46,13 @@ public: SharedPromise(SharedPromise&&) noexcept; SharedPromise& operator=(SharedPromise&&) noexcept; + /** + * Provide a way to split a Future. Note that while the Futures from + * `getFuture()' depend on the completion of the parameter Future they do not + * inherit any other properties such as Executor's passed to `via' etc. + */ + explicit SharedPromise(Future); + /** * Return a Future tied to the shared core state. Unlike Promise::getFuture, * this can be called an unlimited number of times per SharedPromise. diff --git a/folly/futures/test/SharedPromiseTest.cpp b/folly/futures/test/SharedPromiseTest.cpp index 36b5169b..b7245cc0 100644 --- a/folly/futures/test/SharedPromiseTest.cpp +++ b/folly/futures/test/SharedPromiseTest.cpp @@ -125,3 +125,33 @@ TEST(SharedPromise, interruptHandler) { f.cancel(); EXPECT_TRUE(flag); } + +TEST(SharedPromise, splitFutureSuccess) { + Promise p; + SharedPromise sp(p.getFuture()); + auto f1 = sp.getFuture(); + EXPECT_FALSE(f1.isReady()); + p.setValue(1); + EXPECT_TRUE(f1.isReady()); + EXPECT_TRUE(f1.hasValue()); + auto f2 = sp.getFuture(); + EXPECT_TRUE(f2.isReady()); + EXPECT_TRUE(f2.hasValue()); +} + +TEST(SharedPromise, splitFutureFailure) { + Promise p; + SharedPromise sp(p.getFuture()); + auto f1 = sp.getFuture(); + EXPECT_FALSE(f1.isReady()); + try { + throw std::runtime_error("Oops"); + } catch (...) { + p.setException(exception_wrapper(std::current_exception())); + } + EXPECT_TRUE(f1.isReady()); + EXPECT_TRUE(f1.hasException()); + auto f2 = sp.getFuture(); + EXPECT_TRUE(f2.isReady()); + EXPECT_TRUE(f2.hasException()); +} -- 2.34.1