2 * Copyright 2014 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <folly/small_vector.h>
20 #include <gtest/gtest.h>
24 #include <type_traits>
26 #include <folly/Memory.h>
27 #include <folly/Executor.h>
28 #include <folly/futures/Future.h>
29 #include <folly/futures/ManualExecutor.h>
30 #include <folly/MPMCQueue.h>
32 #include <folly/io/async/Request.h>
34 using namespace folly;
37 using std::unique_ptr;
40 #define EXPECT_TYPE(x, T) \
41 EXPECT_TRUE((std::is_same<decltype(x), T>::value))
43 /// Simple executor that does work in another thread
44 class ThreadExecutor : public Executor {
45 folly::MPMCQueue<Func> funcs;
46 std::atomic<bool> done {false};
54 while (!funcs.isEmpty()) {
55 funcs.blockingRead(fn);
62 explicit ThreadExecutor(size_t n = 1024)
63 : funcs(n), worker(std::bind(&ThreadExecutor::work, this)) {}
71 void add(Func fn) override {
72 funcs.blockingWrite(std::move(fn));
75 void waitForStartup() {
80 typedef FutureException eggs_t;
81 static eggs_t eggs("eggs");
85 TEST(Future, onError) {
87 auto flag = [&]{ theFlag = true; };
88 #define EXPECT_FLAG() \
90 EXPECT_TRUE(theFlag); \
94 #define EXPECT_NO_FLAG() \
96 EXPECT_FALSE(theFlag); \
102 auto f = makeFuture()
103 .then([] { throw eggs; })
104 .onError([&] (eggs_t& e) { flag(); });
106 EXPECT_NO_THROW(f.value());
110 auto f = makeFuture()
111 .then([] { throw eggs; })
112 .onError([&] (eggs_t& e) { flag(); return makeFuture(); });
114 EXPECT_NO_THROW(f.value());
119 auto f = makeFuture()
120 .then([] { throw eggs; })
121 .onError([&] (eggs_t e) { flag(); });
123 EXPECT_NO_THROW(f.value());
127 auto f = makeFuture()
128 .then([] { throw eggs; })
129 .onError([&] (eggs_t e) { flag(); return makeFuture(); });
131 EXPECT_NO_THROW(f.value());
136 auto f = makeFuture()
137 .then([] { throw eggs; })
138 .onError([&] (std::exception& e) { flag(); });
140 EXPECT_NO_THROW(f.value());
144 auto f = makeFuture()
145 .then([] { throw eggs; })
146 .onError([&] (std::exception& e) { flag(); return makeFuture(); });
148 EXPECT_NO_THROW(f.value());
153 auto f = makeFuture()
154 .then([] { throw -1; })
155 .onError([&] (int e) { flag(); });
157 EXPECT_NO_THROW(f.value());
161 auto f = makeFuture()
162 .then([] { throw -1; })
163 .onError([&] (int e) { flag(); return makeFuture(); });
165 EXPECT_NO_THROW(f.value());
170 auto f = makeFuture()
171 .then([] { throw eggs; })
172 .onError([&] (eggs_t& e) mutable { flag(); });
174 EXPECT_NO_THROW(f.value());
178 auto f = makeFuture()
179 .then([] { throw eggs; })
180 .onError([&] (eggs_t& e) mutable { flag(); return makeFuture(); });
182 EXPECT_NO_THROW(f.value());
187 auto f = makeFuture()
188 .then([] { return 42; })
189 .onError([&] (eggs_t& e) { flag(); return -1; });
191 EXPECT_EQ(42, f.value());
195 auto f = makeFuture()
196 .then([] { return 42; })
197 .onError([&] (eggs_t& e) { flag(); return makeFuture<int>(-1); });
199 EXPECT_EQ(42, f.value());
202 // Catch different exception
204 auto f = makeFuture()
205 .then([] { throw eggs; })
206 .onError([&] (std::runtime_error& e) { flag(); });
208 EXPECT_THROW(f.value(), eggs_t);
212 auto f = makeFuture()
213 .then([] { throw eggs; })
214 .onError([&] (std::runtime_error& e) { flag(); return makeFuture(); });
216 EXPECT_THROW(f.value(), eggs_t);
219 // Returned value propagates
221 auto f = makeFuture()
222 .then([] { throw eggs; return 0; })
223 .onError([&] (eggs_t& e) { return 42; });
224 EXPECT_EQ(42, f.value());
227 // Returned future propagates
229 auto f = makeFuture()
230 .then([] { throw eggs; return 0; })
231 .onError([&] (eggs_t& e) { return makeFuture<int>(42); });
232 EXPECT_EQ(42, f.value());
237 auto f = makeFuture()
238 .then([] { throw eggs; return 0; })
239 .onError([&] (eggs_t& e) { throw e; return -1; });
240 EXPECT_THROW(f.value(), eggs_t);
244 auto f = makeFuture()
245 .then([] { throw eggs; return 0; })
246 .onError([&] (eggs_t& e) { throw e; return makeFuture<int>(-1); });
247 EXPECT_THROW(f.value(), eggs_t);
264 Try<A> t_a(std::move(a));
268 EXPECT_EQ(5, t_a.value().x());
271 TEST(Future, special) {
272 EXPECT_FALSE(std::is_copy_constructible<Future<int>>::value);
273 EXPECT_FALSE(std::is_copy_assignable<Future<int>>::value);
274 EXPECT_TRUE(std::is_move_constructible<Future<int>>::value);
275 EXPECT_TRUE(std::is_move_assignable<Future<int>>::value);
278 TEST(Future, thenTry) {
281 makeFuture<int>(42).then([&](Try<int>&& t) {
283 EXPECT_EQ(42, t.value());
285 EXPECT_TRUE(flag); flag = false;
288 .then([](Try<int>&& t) { return t.value(); })
289 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
290 EXPECT_TRUE(flag); flag = false;
292 makeFuture().then([&](Try<void>&& t) { flag = true; t.value(); });
293 EXPECT_TRUE(flag); flag = false;
296 auto f = p.getFuture().then([&](Try<void>&& t) { flag = true; });
298 EXPECT_FALSE(f.isReady());
301 EXPECT_TRUE(f.isReady());
304 TEST(Future, thenValue) {
306 makeFuture<int>(42).then([&](int i){
310 EXPECT_TRUE(flag); flag = false;
313 .then([](int i){ return i; })
314 .then([&](int i) { flag = true; EXPECT_EQ(42, i); });
315 EXPECT_TRUE(flag); flag = false;
317 makeFuture().then([&]{
320 EXPECT_TRUE(flag); flag = false;
322 auto f = makeFuture<int>(eggs).then([&](int i){});
323 EXPECT_THROW(f.value(), eggs_t);
325 f = makeFuture<void>(eggs).then([&]{});
326 EXPECT_THROW(f.value(), eggs_t);
329 TEST(Future, thenValueFuture) {
332 .then([](int i){ return makeFuture<int>(std::move(i)); })
333 .then([&](Try<int>&& t) { flag = true; EXPECT_EQ(42, t.value()); });
334 EXPECT_TRUE(flag); flag = false;
337 .then([]{ return makeFuture(); })
338 .then([&](Try<void>&& t) { flag = true; });
339 EXPECT_TRUE(flag); flag = false;
342 static string doWorkStatic(Try<string>&& t) {
343 return t.value() + ";static";
346 TEST(Future, thenFunction) {
348 string doWork(Try<string>&& t) {
349 return t.value() + ";class";
351 static string doWorkStatic(Try<string>&& t) {
352 return t.value() + ";class-static";
356 auto f = makeFuture<string>("start")
358 .then(Worker::doWorkStatic)
359 .then(&w, &Worker::doWork);
361 EXPECT_EQ(f.value(), "start;static;class-static;class");
364 static Future<string> doWorkStaticFuture(Try<string>&& t) {
365 return makeFuture(t.value() + ";static");
368 TEST(Future, thenFunctionFuture) {
370 Future<string> doWorkFuture(Try<string>&& t) {
371 return makeFuture(t.value() + ";class");
373 static Future<string> doWorkStaticFuture(Try<string>&& t) {
374 return makeFuture(t.value() + ";class-static");
378 auto f = makeFuture<string>("start")
379 .then(doWorkStaticFuture)
380 .then(Worker::doWorkStaticFuture)
381 .then(&w, &Worker::doWorkFuture);
383 EXPECT_EQ(f.value(), "start;static;class-static;class");
386 TEST(Future, value) {
387 auto f = makeFuture(unique_ptr<int>(new int(42)));
388 auto up = std::move(f.value());
391 EXPECT_THROW(makeFuture<int>(eggs).value(), eggs_t);
394 TEST(Future, isReady) {
396 auto f = p.getFuture();
397 EXPECT_FALSE(f.isReady());
399 EXPECT_TRUE(f.isReady());
402 TEST(Future, futureNotReady) {
404 Future<int> f = p.getFuture();
405 EXPECT_THROW(f.value(), eggs_t);
408 TEST(Future, hasException) {
409 EXPECT_TRUE(makeFuture<int>(eggs).getTry().hasException());
410 EXPECT_FALSE(makeFuture(42).getTry().hasException());
413 TEST(Future, hasValue) {
414 EXPECT_TRUE(makeFuture(42).getTry().hasValue());
415 EXPECT_FALSE(makeFuture<int>(eggs).getTry().hasValue());
418 TEST(Future, makeFuture) {
419 EXPECT_TYPE(makeFuture(42), Future<int>);
420 EXPECT_EQ(42, makeFuture(42).value());
422 EXPECT_TYPE(makeFuture<float>(42), Future<float>);
423 EXPECT_EQ(42, makeFuture<float>(42).value());
425 auto fun = [] { return 42; };
426 EXPECT_TYPE(makeFutureTry(fun), Future<int>);
427 EXPECT_EQ(42, makeFutureTry(fun).value());
429 auto failfun = []() -> int { throw eggs; };
430 EXPECT_TYPE(makeFutureTry(failfun), Future<int>);
431 EXPECT_THROW(makeFutureTry(failfun).value(), eggs_t);
433 EXPECT_TYPE(makeFuture(), Future<void>);
438 TEST(Promise, special) {
439 EXPECT_FALSE(std::is_copy_constructible<Promise<int>>::value);
440 EXPECT_FALSE(std::is_copy_assignable<Promise<int>>::value);
441 EXPECT_TRUE(std::is_move_constructible<Promise<int>>::value);
442 EXPECT_TRUE(std::is_move_assignable<Promise<int>>::value);
445 TEST(Promise, getFuture) {
447 Future<int> f = p.getFuture();
448 EXPECT_FALSE(f.isReady());
451 TEST(Promise, setValue) {
453 auto ffund = fund.getFuture();
455 EXPECT_EQ(42, ffund.value());
463 auto fpod = pod.getFuture();
464 Foo f = {"the answer", 42};
466 Foo f2 = fpod.value();
467 EXPECT_EQ(f.name, f2.name);
468 EXPECT_EQ(f.value, f2.value);
470 pod = Promise<Foo>();
471 fpod = pod.getFuture();
472 pod.setValue(std::move(f2));
473 Foo f3 = fpod.value();
474 EXPECT_EQ(f.name, f3.name);
475 EXPECT_EQ(f.value, f3.value);
477 Promise<unique_ptr<int>> mov;
478 auto fmov = mov.getFuture();
479 mov.setValue(unique_ptr<int>(new int(42)));
480 unique_ptr<int> ptr = std::move(fmov.value());
484 auto fv = v.getFuture();
486 EXPECT_TRUE(fv.isReady());
489 TEST(Promise, setException) {
492 auto f = p.getFuture();
493 p.setException(eggs);
494 EXPECT_THROW(f.value(), eggs_t);
498 auto f = p.getFuture();
502 p.setException(exception_wrapper(std::current_exception()));
504 EXPECT_THROW(f.value(), eggs_t);
508 TEST(Promise, fulfil) {
511 auto f = p.getFuture();
512 p.fulfil([] { return 42; });
513 EXPECT_EQ(42, f.value());
517 auto f = p.getFuture();
518 p.fulfil([]() -> int { throw eggs; });
519 EXPECT_THROW(f.value(), eggs_t);
523 TEST(Future, finish) {
524 auto x = std::make_shared<int>(0);
527 auto f = p.getFuture().then([x](Try<int>&& t) { *x = t.value(); });
529 // The callback hasn't executed
532 // The callback has a reference to x
533 EXPECT_EQ(2, x.use_count());
537 // the callback has executed
540 // the callback has been destructed
541 // and has released its reference to x
542 EXPECT_EQ(1, x.use_count());
545 TEST(Future, unwrap) {
549 auto fa = a.getFuture();
550 auto fb = b.getFuture();
555 // do a, then do b, and get the result of a + b.
556 Future<int> f = fa.then([&](Try<int>&& ta) {
557 auto va = ta.value();
559 return fb.then([va, &flag2](Try<int>&& tb) {
561 return va + tb.value();
567 EXPECT_FALSE(f.isReady());
572 EXPECT_FALSE(f.isReady());
577 EXPECT_EQ(7, f.value());
580 TEST(Future, whenAll) {
581 // returns a vector variant
583 vector<Promise<int>> promises(10);
584 vector<Future<int>> futures;
586 for (auto& p : promises)
587 futures.push_back(p.getFuture());
589 auto allf = whenAll(futures.begin(), futures.end());
591 random_shuffle(promises.begin(), promises.end());
592 for (auto& p : promises) {
593 EXPECT_FALSE(allf.isReady());
597 EXPECT_TRUE(allf.isReady());
598 auto& results = allf.value();
599 for (auto& t : results) {
600 EXPECT_EQ(42, t.value());
604 // check error semantics
606 vector<Promise<int>> promises(4);
607 vector<Future<int>> futures;
609 for (auto& p : promises)
610 futures.push_back(p.getFuture());
612 auto allf = whenAll(futures.begin(), futures.end());
615 promises[0].setValue(42);
616 promises[1].setException(eggs);
618 EXPECT_FALSE(allf.isReady());
620 promises[2].setValue(42);
622 EXPECT_FALSE(allf.isReady());
624 promises[3].setException(eggs);
626 EXPECT_TRUE(allf.isReady());
627 EXPECT_FALSE(allf.getTry().hasException());
629 auto& results = allf.value();
630 EXPECT_EQ(42, results[0].value());
631 EXPECT_TRUE(results[1].hasException());
632 EXPECT_EQ(42, results[2].value());
633 EXPECT_TRUE(results[3].hasException());
636 // check that futures are ready in then()
638 vector<Promise<void>> promises(10);
639 vector<Future<void>> futures;
641 for (auto& p : promises)
642 futures.push_back(p.getFuture());
644 auto allf = whenAll(futures.begin(), futures.end())
645 .then([](Try<vector<Try<void>>>&& ts) {
646 for (auto& f : ts.value())
650 random_shuffle(promises.begin(), promises.end());
651 for (auto& p : promises)
653 EXPECT_TRUE(allf.isReady());
658 TEST(Future, whenAny) {
660 vector<Promise<int>> promises(10);
661 vector<Future<int>> futures;
663 for (auto& p : promises)
664 futures.push_back(p.getFuture());
666 for (auto& f : futures) {
667 EXPECT_FALSE(f.isReady());
670 auto anyf = whenAny(futures.begin(), futures.end());
672 /* futures were moved in, so these are invalid now */
673 EXPECT_FALSE(anyf.isReady());
675 promises[7].setValue(42);
676 EXPECT_TRUE(anyf.isReady());
677 auto& idx_fut = anyf.value();
679 auto i = idx_fut.first;
682 auto& f = idx_fut.second;
683 EXPECT_EQ(42, f.value());
688 vector<Promise<void>> promises(10);
689 vector<Future<void>> futures;
691 for (auto& p : promises)
692 futures.push_back(p.getFuture());
694 for (auto& f : futures) {
695 EXPECT_FALSE(f.isReady());
698 auto anyf = whenAny(futures.begin(), futures.end());
700 EXPECT_FALSE(anyf.isReady());
702 promises[3].setException(eggs);
703 EXPECT_TRUE(anyf.isReady());
704 EXPECT_TRUE(anyf.value().second.hasException());
709 vector<Promise<int>> promises(10);
710 vector<Future<int>> futures;
712 for (auto& p : promises)
713 futures.push_back(p.getFuture());
715 auto anyf = whenAny(futures.begin(), futures.end())
716 .then([](Try<pair<size_t, Try<int>>>&& f) {
717 EXPECT_EQ(42, f.value().second.value());
720 promises[3].setValue(42);
721 EXPECT_TRUE(anyf.isReady());
726 TEST(when, already_completed) {
728 vector<Future<void>> fs;
729 for (int i = 0; i < 10; i++)
730 fs.push_back(makeFuture());
732 whenAll(fs.begin(), fs.end())
733 .then([&](Try<vector<Try<void>>>&& t) {
734 EXPECT_EQ(fs.size(), t.value().size());
738 vector<Future<int>> fs;
739 for (int i = 0; i < 10; i++)
740 fs.push_back(makeFuture(i));
742 whenAny(fs.begin(), fs.end())
743 .then([&](Try<pair<size_t, Try<int>>>&& t) {
745 EXPECT_EQ(p.first, p.second.value());
751 vector<Promise<void>> promises(10);
752 vector<Future<void>> futures;
754 for (auto& p : promises)
755 futures.push_back(p.getFuture());
759 whenN(futures.begin(), futures.end(), n)
760 .then([&](Try<vector<pair<size_t, Try<void>>>>&& t) {
763 EXPECT_EQ(n, v.size());
765 EXPECT_TRUE(tt.second.hasValue());
768 promises[0].setValue();
770 promises[1].setValue();
772 promises[2].setValue();
776 /* Ensure that we can compile when_{all,any} with folly::small_vector */
777 TEST(when, small_vector) {
779 static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<void>),
780 "Futures should not be trivially copyable");
781 static_assert(!FOLLY_IS_TRIVIALLY_COPYABLE(Future<int>),
782 "Futures should not be trivially copyable");
784 using folly::small_vector;
786 small_vector<Future<void>> futures;
788 for (int i = 0; i < 10; i++)
789 futures.push_back(makeFuture());
791 auto anyf = whenAny(futures.begin(), futures.end());
795 small_vector<Future<void>> futures;
797 for (int i = 0; i < 10; i++)
798 futures.push_back(makeFuture());
800 auto allf = whenAll(futures.begin(), futures.end());
804 TEST(Future, whenAllVariadic) {
807 Future<bool> fb = pb.getFuture();
808 Future<int> fi = pi.getFuture();
810 whenAll(std::move(fb), std::move(fi))
811 .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
813 EXPECT_TRUE(t.hasValue());
814 EXPECT_TRUE(std::get<0>(t.value()).hasValue());
815 EXPECT_EQ(std::get<0>(t.value()).value(), true);
816 EXPECT_TRUE(std::get<1>(t.value()).hasValue());
817 EXPECT_EQ(std::get<1>(t.value()).value(), 42);
825 TEST(Future, whenAllVariadicReferences) {
828 Future<bool> fb = pb.getFuture();
829 Future<int> fi = pi.getFuture();
832 .then([&](Try<std::tuple<Try<bool>, Try<int>>>&& t) {
834 EXPECT_TRUE(t.hasValue());
835 EXPECT_TRUE(std::get<0>(t.value()).hasValue());
836 EXPECT_EQ(std::get<0>(t.value()).value(), true);
837 EXPECT_TRUE(std::get<1>(t.value()).hasValue());
838 EXPECT_EQ(std::get<1>(t.value()).value(), 42);
846 TEST(Future, whenAll_none) {
847 vector<Future<int>> fs;
848 auto f = whenAll(fs.begin(), fs.end());
849 EXPECT_TRUE(f.isReady());
852 TEST(Future, throwCaughtInImmediateThen) {
853 // Neither of these should throw "Promise already satisfied"
855 [=](Try<void>&&) -> int { throw std::exception(); });
857 [=](Try<void>&&) -> Future<int> { throw std::exception(); });
860 TEST(Future, throwIfFailed) {
861 makeFuture<void>(eggs)
862 .then([=](Try<void>&& t) {
863 EXPECT_THROW(t.throwIfFailed(), eggs_t);
866 .then([=](Try<void>&& t) {
867 EXPECT_NO_THROW(t.throwIfFailed());
870 makeFuture<int>(eggs)
871 .then([=](Try<int>&& t) {
872 EXPECT_THROW(t.throwIfFailed(), eggs_t);
875 .then([=](Try<int>&& t) {
876 EXPECT_NO_THROW(t.throwIfFailed());
880 TEST(Future, waitWithSemaphoreImmediate) {
881 waitWithSemaphore(makeFuture());
882 auto done = waitWithSemaphore(makeFuture(42)).value();
885 vector<int> v{1,2,3};
886 auto done_v = waitWithSemaphore(makeFuture(v)).value();
887 EXPECT_EQ(v.size(), done_v.size());
888 EXPECT_EQ(v, done_v);
890 vector<Future<void>> v_f;
891 v_f.push_back(makeFuture());
892 v_f.push_back(makeFuture());
893 auto done_v_f = waitWithSemaphore(whenAll(v_f.begin(), v_f.end())).value();
894 EXPECT_EQ(2, done_v_f.size());
896 vector<Future<bool>> v_fb;
897 v_fb.push_back(makeFuture(true));
898 v_fb.push_back(makeFuture(false));
899 auto fut = whenAll(v_fb.begin(), v_fb.end());
900 auto done_v_fb = std::move(waitWithSemaphore(std::move(fut)).value());
901 EXPECT_EQ(2, done_v_fb.size());
904 TEST(Future, waitWithSemaphore) {
906 Future<int> f = p.getFuture();
907 std::atomic<bool> flag{false};
908 std::atomic<int> result{1};
909 std::atomic<std::thread::id> id;
911 std::thread t([&](Future<int>&& tf){
912 auto n = tf.then([&](Try<int> && t) {
913 id = std::this_thread::get_id();
917 result.store(waitWithSemaphore(std::move(n)).value());
922 EXPECT_EQ(result.load(), 1);
925 // validate that the callback ended up executing in this thread, which
926 // is more to ensure that this test actually tests what it should
927 EXPECT_EQ(id, std::this_thread::get_id());
928 EXPECT_EQ(result.load(), 42);
931 TEST(Future, waitWithSemaphoreForTime) {
934 Future<int> f = p.getFuture();
935 auto t = waitWithSemaphore(std::move(f),
936 std::chrono::microseconds(1));
937 EXPECT_FALSE(t.isReady());
939 EXPECT_TRUE(t.isReady());
943 Future<int> f = p.getFuture();
945 auto t = waitWithSemaphore(std::move(f),
946 std::chrono::milliseconds(1));
947 EXPECT_TRUE(t.isReady());
950 vector<Future<bool>> v_fb;
951 v_fb.push_back(makeFuture(true));
952 v_fb.push_back(makeFuture(false));
953 auto f = whenAll(v_fb.begin(), v_fb.end());
954 auto t = waitWithSemaphore(std::move(f),
955 std::chrono::milliseconds(1));
956 EXPECT_TRUE(t.isReady());
957 EXPECT_EQ(2, t.value().size());
960 vector<Future<bool>> v_fb;
963 v_fb.push_back(p1.getFuture());
964 v_fb.push_back(p2.getFuture());
965 auto f = whenAll(v_fb.begin(), v_fb.end());
966 auto t = waitWithSemaphore(std::move(f),
967 std::chrono::milliseconds(1));
968 EXPECT_FALSE(t.isReady());
970 EXPECT_FALSE(t.isReady());
972 EXPECT_TRUE(t.isReady());
975 auto t = waitWithSemaphore(makeFuture(),
976 std::chrono::milliseconds(1));
977 EXPECT_TRUE(t.isReady());
981 TEST(Future, callbackAfterActivate) {
983 auto f = p.getFuture();
987 f.then([&](Try<void>&&) { count++; });
996 TEST(Future, activateOnDestruct) {
997 auto f = std::make_shared<Future<void>>(makeFuture());
1001 f->then([&](Try<void>&&) { count++; });
1002 EXPECT_EQ(0, count);
1005 EXPECT_EQ(1, count);
1008 TEST(Future, viaActsCold) {
1013 fv.then([&](Try<void>&&) { count++; });
1015 EXPECT_EQ(0, count);
1019 EXPECT_EQ(1, x.run());
1020 EXPECT_EQ(1, count);
1023 TEST(Future, viaIsCold) {
1025 EXPECT_FALSE(via(&x).isActive());
1028 TEST(Future, viaRaces) {
1031 auto tid = std::this_thread::get_id();
1034 std::thread t1([&] {
1037 .then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
1038 .then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
1039 .then([&](Try<void>&&) { done = true; });
1042 std::thread t2([&] {
1046 while (!done) x.run();
1052 TEST(Future, viaRaces_2stage) {
1055 auto tid = std::this_thread::get_id();
1058 std::thread t1([&] {
1059 auto f2 = p.getFuture().via(&x);
1060 f2.then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
1061 .then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
1062 .then([&](Try<void>&&) { done = true; });
1064 // the bug was in the promise being fulfilled before f2 is reactivated. we
1065 // could sleep, but yielding should cause this to fail with reasonable
1067 std::this_thread::yield();
1071 std::thread t2([&] {
1075 while (!done) x.run();
1080 TEST(Future, getFuture_after_setValue) {
1083 EXPECT_EQ(42, p.getFuture().value());
1086 TEST(Future, getFuture_after_setException) {
1088 p.fulfil([]() -> void { throw std::logic_error("foo"); });
1089 EXPECT_THROW(p.getFuture().value(), std::logic_error);
1092 TEST(Future, detachRace) {
1094 // This test is designed to detect a race that was in Core::detachOne()
1095 // where detached_ was incremented and then tested, and that
1096 // allowed a race where both Promise and Future would think they were the
1097 // second and both try to delete. This showed up at scale but was very
1098 // difficult to reliably repro in a test. As it is, this only fails about
1099 // once in every 1,000 executions. Doing this 1,000 times is going to make a
1100 // slow test so I won't do that but if it ever fails, take it seriously, and
1101 // run the test binary with "--gtest_repeat=10000 --gtest_filter=*detachRace"
1102 // (Don't forget to enable ASAN)
1103 auto p = folly::make_unique<Promise<bool>>();
1104 auto f = folly::make_unique<Future<bool>>(p->getFuture());
1105 folly::Baton<> baton;
1115 class TestData : public RequestData {
1117 explicit TestData(int data) : data_(data) {}
1118 virtual ~TestData() {}
1122 TEST(Future, context) {
1124 // Start a new context
1125 RequestContext::create();
1127 EXPECT_EQ(nullptr, RequestContext::get()->getContextData("test"));
1129 // Set some test data
1130 RequestContext::get()->setContextData(
1132 std::unique_ptr<TestData>(new TestData(10)));
1136 auto future = p.getFuture().then([&]{
1137 // Check that the context followed the future
1138 EXPECT_TRUE(RequestContext::get() != nullptr);
1139 auto a = dynamic_cast<TestData*>(
1140 RequestContext::get()->getContextData("test"));
1141 auto data = a->data_;
1142 EXPECT_EQ(10, data);
1145 // Clear the context
1146 RequestContext::setContext(nullptr);
1148 EXPECT_EQ(nullptr, RequestContext::get()->getContextData("test"));
1150 // Fulfil the promise
1155 // This only fails about 1 in 1k times when the bug is present :(
1156 TEST(Future, t5506504) {
1160 auto promises = std::make_shared<vector<Promise<void>>>(4);
1161 vector<Future<void>> futures;
1163 for (auto& p : *promises) {
1164 futures.emplace_back(
1167 .then([](Try<void>&&){}));
1172 for (auto& p : *promises) p.setValue();
1175 return whenAll(futures.begin(), futures.end());
1178 waitWithSemaphore(fn());
1181 // Test of handling of a circular dependency. It's never recommended
1182 // to have one because of possible memory leaks. Here we test that
1183 // we can handle freeing of the Future while it is running.
1184 TEST(Future, CircularDependencySharedPtrSelfReset) {
1185 Promise<int64_t> promise;
1186 auto ptr = std::make_shared<Future<int64_t>>(promise.getFuture());
1189 [ptr] (folly::Try<int64_t>&& uid) mutable {
1190 EXPECT_EQ(1, ptr.use_count());
1192 // Leaving no references to ourselves.
1194 EXPECT_EQ(0, ptr.use_count());
1198 EXPECT_EQ(2, ptr.use_count());
1202 promise.fulfil([]{return 1l;});