Make SemiFuture::via throw on nullptr executor.
authorLee Howes <lwh@fb.com>
Sat, 4 Nov 2017 02:51:04 +0000 (19:51 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Sat, 4 Nov 2017 02:53:20 +0000 (19:53 -0700)
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
folly/futures/FutureException.cpp
folly/futures/FutureException.h
folly/futures/test/SemiFutureTest.cpp

index 20cf87b..dea9e86 100644 (file)
@@ -483,6 +483,9 @@ void SemiFuture<T>::boost_() {
 template <class T>
 inline Future<T> SemiFuture<T>::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.
index ecbf03d..d21d6f9 100644 (file)
@@ -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
index 9d3bd77..0df8d8b 100644 (file)
@@ -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
index 9531483..39ea108 100644 (file)
@@ -143,6 +143,10 @@ TEST(SemiFuture, makeSemiFutureNoThrow) {
   makeSemiFuture().value();
 }
 
+TEST(SemiFuture, ViaThrowOnNull) {
+  EXPECT_THROW(makeSemiFuture().via(nullptr), NoExecutor);
+}
+
 TEST(SemiFuture, ConstructSemiFutureFromEmptyFuture) {
   auto f = SemiFuture<int>{Future<int>::makeEmpty()};
   EXPECT_THROW(f.isReady(), NoState);