Commit 031ed38a authored by Hannes Roth's avatar Hannes Roth Committed by facebook-github-bot-4

(Wangle) within should raise TimedOut()

Summary: A timeout now raises `TimedOut()` on the current Future.

Reviewed By: @fugalh

Differential Revision: D2261559
parent d3928f05
...@@ -857,17 +857,27 @@ Future<T> Future<T>::within(Duration dur, E e, Timekeeper* tk) { ...@@ -857,17 +857,27 @@ Future<T> Future<T>::within(Duration dur, E e, Timekeeper* tk) {
struct Context { struct Context {
Context(E ex) : exception(std::move(ex)), promise() {} Context(E ex) : exception(std::move(ex)), promise() {}
E exception; E exception;
Future<Unit> thisFuture;
Promise<T> promise; Promise<T> promise;
std::atomic<bool> token {false}; std::atomic<bool> token {false};
}; };
auto ctx = std::make_shared<Context>(std::move(e));
if (!tk) { if (!tk) {
tk = folly::detail::getTimekeeperSingleton(); tk = folly::detail::getTimekeeperSingleton();
} }
tk->after(dur) auto ctx = std::make_shared<Context>(std::move(e));
.then([ctx](Try<Unit> const& t) {
ctx->thisFuture = this->then([ctx](Try<T>&& t) mutable {
// TODO: "this" completed first, cancel "after"
if (ctx->token.exchange(true) == false) {
ctx->promise.setTry(std::move(t));
}
});
tk->after(dur).then([ctx](Try<Unit> const& t) mutable {
// "after" completed first, cancel "this"
ctx->thisFuture.raise(TimedOut());
if (ctx->token.exchange(true) == false) { if (ctx->token.exchange(true) == false) {
if (t.hasException()) { if (t.hasException()) {
ctx->promise.setException(std::move(t.exception())); ctx->promise.setException(std::move(t.exception()));
...@@ -877,12 +887,6 @@ Future<T> Future<T>::within(Duration dur, E e, Timekeeper* tk) { ...@@ -877,12 +887,6 @@ Future<T> Future<T>::within(Duration dur, E e, Timekeeper* tk) {
} }
}); });
this->then([ctx](Try<T>&& t) {
if (ctx->token.exchange(true) == false) {
ctx->promise.setTry(std::move(t));
}
});
return ctx->promise.getFuture().via(getExecutor()); return ctx->promise.getFuture().via(getExecutor());
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <folly/futures/Future.h> #include <folly/futures/Future.h>
#include <folly/futures/Promise.h> #include <folly/futures/Promise.h>
#include <folly/Baton.h>
using namespace folly; using namespace folly;
...@@ -72,3 +73,13 @@ TEST(Interrupt, secondInterruptNoop) { ...@@ -72,3 +73,13 @@ TEST(Interrupt, secondInterruptNoop) {
f.cancel(); f.cancel();
EXPECT_EQ(1, count); EXPECT_EQ(1, count);
} }
TEST(Interrupt, withinTimedOut) {
Promise<int> p;
Baton<> done;
p.setInterruptHandler([&](const exception_wrapper& e) { done.post(); });
p.getFuture().within(std::chrono::milliseconds(1));
// Give it 100ms to time out and call the interrupt handler
auto t = std::chrono::steady_clock::now() + std::chrono::milliseconds(100);
EXPECT_TRUE(done.timed_wait(t));
}
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