fix dead-lock in Future when executor discards function
[folly.git] / folly / futures / test / ViaTest.cpp
index 765fdf6c74010f9b62127ab8bd5505f3b57c0a2e..bbbd96a27e7105439e2c7bd5ea2f4ad2bcce6a1f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -143,9 +143,9 @@ TEST_F(ViaFixture, chainVias) {
     return 1;
   }).then([=](int val) {
     return makeFuture(val).via(westExecutor.get())
-      .then([=](int val) mutable {
+      .then([=](int v) mutable {
         EXPECT_EQ(std::this_thread::get_id(), westThreadId);
-        return val + 1;
+        return v + 1;
       });
   }).then([=](int val) {
     // even though ultimately the future that triggers this one executed in
@@ -400,6 +400,32 @@ TEST(Via, getVia) {
   }
 }
 
+TEST(Via, getTryVia) {
+  {
+    // non-void
+    ManualExecutor x;
+    auto f = via(&x).then([] { return 23; });
+    EXPECT_FALSE(f.isReady());
+    EXPECT_EQ(23, f.getTryVia(&x).value());
+  }
+
+  {
+    // void
+    ManualExecutor x;
+    auto f = via(&x).then();
+    EXPECT_FALSE(f.isReady());
+    auto t = f.getTryVia(&x);
+    EXPECT_TRUE(t.hasValue());
+  }
+
+  {
+    DummyDrivableExecutor x;
+    auto f = makeFuture(23);
+    EXPECT_EQ(23, f.getTryVia(&x).value());
+    EXPECT_FALSE(x.ran);
+  }
+}
+
 TEST(Via, waitVia) {
   {
     ManualExecutor x;
@@ -446,6 +472,22 @@ TEST(Via, viaRaces) {
   t2.join();
 }
 
+TEST(Via, viaDummyExecutorFutureSetValueFirst) {
+  DummyDrivableExecutor x;
+  auto future = makeFuture().via(&x).then([] { return 42; });
+
+  EXPECT_THROW(future.get(), BrokenPromise);
+}
+
+TEST(Via, viaDummyExecutorFutureSetCallbackFirst) {
+  DummyDrivableExecutor x;
+  Promise<Unit> trigger;
+  auto future = trigger.getFuture().via(&x).then([] { return 42; });
+  trigger.setValue();
+
+  EXPECT_THROW(future.get(), BrokenPromise);
+}
+
 TEST(ViaFunc, liftsVoid) {
   ManualExecutor x;
   int count = 0;