From 36ae3c3e9403dcef4677834bc920a70e15ddcbab Mon Sep 17 00:00:00 2001 From: Lee Howes Date: Fri, 3 Nov 2017 19:51:04 -0700 Subject: [PATCH] Make SemiFuture::via throw on nullptr executor. Summary: Make SemiFuture throw if no executor provided to via because in that situation the deferred work will never run. Reviewed By: yfeldblum Differential Revision: D6233233 fbshipit-source-id: 43b642c46cc0be80b1f13c03bdaf20b8038acec2 --- folly/futures/Future-inl.h | 3 +++ folly/futures/FutureException.cpp | 6 ++++-- folly/futures/FutureException.h | 7 +++++++ folly/futures/test/SemiFutureTest.cpp | 4 ++++ 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/folly/futures/Future-inl.h b/folly/futures/Future-inl.h index 20cf87bc..dea9e863 100644 --- a/folly/futures/Future-inl.h +++ b/folly/futures/Future-inl.h @@ -483,6 +483,9 @@ void SemiFuture::boost_() { template inline Future SemiFuture::via(Executor* executor, int8_t priority) && { throwIfInvalid(); + if (!executor) { + throwNoExecutor(); + } // If current executor is deferred, boost block to ensure that work // progresses and is run on the new executor. diff --git a/folly/futures/FutureException.cpp b/folly/futures/FutureException.cpp index ecbf03da..d21d6f94 100644 --- a/folly/futures/FutureException.cpp +++ b/folly/futures/FutureException.cpp @@ -42,7 +42,9 @@ namespace folly { throw PredicateDoesNotObtain(); } -[[noreturn]] void throwNoFutureInSplitter() { - throw NoFutureInSplitter(); +[[noreturn]] void throwNoFutureInSplitter() { throw NoFutureInSplitter(); } + + [[noreturn]] void throwNoExecutor() { + throw NoExecutor(); } } // namespace folly diff --git a/folly/futures/FutureException.h b/folly/futures/FutureException.h index 9d3bd77d..0df8d8b3 100644 --- a/folly/futures/FutureException.h +++ b/folly/futures/FutureException.h @@ -94,4 +94,11 @@ class FOLLY_EXPORT NoTimekeeper : public FutureException { public: NoTimekeeper() : FutureException("No timekeeper available") {} }; + +[[noreturn]] void throwNoExecutor(); + +class FOLLY_EXPORT NoExecutor : public FutureException { + public: + NoExecutor() : FutureException("No executor provided to via") {} +}; } // namespace folly diff --git a/folly/futures/test/SemiFutureTest.cpp b/folly/futures/test/SemiFutureTest.cpp index 95314832..39ea108b 100644 --- a/folly/futures/test/SemiFutureTest.cpp +++ b/folly/futures/test/SemiFutureTest.cpp @@ -143,6 +143,10 @@ TEST(SemiFuture, makeSemiFutureNoThrow) { makeSemiFuture().value(); } +TEST(SemiFuture, ViaThrowOnNull) { + EXPECT_THROW(makeSemiFuture().via(nullptr), NoExecutor); +} + TEST(SemiFuture, ConstructSemiFutureFromEmptyFuture) { auto f = SemiFuture{Future::makeEmpty()}; EXPECT_THROW(f.isReady(), NoState); -- 2.34.1