Commit 36ae3c3e authored by Lee Howes's avatar Lee Howes Committed by Facebook Github Bot

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
parent 2e1b273c
...@@ -483,6 +483,9 @@ void SemiFuture<T>::boost_() { ...@@ -483,6 +483,9 @@ void SemiFuture<T>::boost_() {
template <class T> template <class T>
inline Future<T> SemiFuture<T>::via(Executor* executor, int8_t priority) && { inline Future<T> SemiFuture<T>::via(Executor* executor, int8_t priority) && {
throwIfInvalid(); throwIfInvalid();
if (!executor) {
throwNoExecutor();
}
// If current executor is deferred, boost block to ensure that work // If current executor is deferred, boost block to ensure that work
// progresses and is run on the new executor. // progresses and is run on the new executor.
......
...@@ -42,7 +42,9 @@ namespace folly { ...@@ -42,7 +42,9 @@ namespace folly {
throw PredicateDoesNotObtain(); throw PredicateDoesNotObtain();
} }
[[noreturn]] void throwNoFutureInSplitter() { [[noreturn]] void throwNoFutureInSplitter() { throw NoFutureInSplitter(); }
throw NoFutureInSplitter();
[[noreturn]] void throwNoExecutor() {
throw NoExecutor();
} }
} // namespace folly } // namespace folly
...@@ -94,4 +94,11 @@ class FOLLY_EXPORT NoTimekeeper : public FutureException { ...@@ -94,4 +94,11 @@ class FOLLY_EXPORT NoTimekeeper : public FutureException {
public: public:
NoTimekeeper() : FutureException("No timekeeper available") {} NoTimekeeper() : FutureException("No timekeeper available") {}
}; };
[[noreturn]] void throwNoExecutor();
class FOLLY_EXPORT NoExecutor : public FutureException {
public:
NoExecutor() : FutureException("No executor provided to via") {}
};
} // namespace folly } // namespace folly
...@@ -143,6 +143,10 @@ TEST(SemiFuture, makeSemiFutureNoThrow) { ...@@ -143,6 +143,10 @@ TEST(SemiFuture, makeSemiFutureNoThrow) {
makeSemiFuture().value(); makeSemiFuture().value();
} }
TEST(SemiFuture, ViaThrowOnNull) {
EXPECT_THROW(makeSemiFuture().via(nullptr), NoExecutor);
}
TEST(SemiFuture, ConstructSemiFutureFromEmptyFuture) { TEST(SemiFuture, ConstructSemiFutureFromEmptyFuture) {
auto f = SemiFuture<int>{Future<int>::makeEmpty()}; auto f = SemiFuture<int>{Future<int>::makeEmpty()};
EXPECT_THROW(f.isReady(), NoState); EXPECT_THROW(f.isReady(), NoState);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment