diff --git a/hpx/lcos/when_some.hpp b/hpx/lcos/when_some.hpp index f3d22c7574f1..139722ce5a1f 100644 --- a/hpx/lcos/when_some.hpp +++ b/hpx/lcos/when_some.hpp @@ -370,18 +370,19 @@ namespace hpx { namespace lcos public: void on_future_ready(std::size_t idx, threads::thread_id_type const& id) { - if (count_.fetch_add(1) + 1 == needed_count_) + std::size_t const new_count = count_.fetch_add(1) + 1; + if (new_count <= needed_count_) { - // reactivate waiting thread only if it's not us - if (id != threads::get_self_id()) { - { - typename mutex_type::scoped_lock l(this->mtx_); - lazy_values_.indices.push_back(idx); - } - threads::set_thread_state(id, threads::pending); - } else { + { + typename mutex_type::scoped_lock l(this->mtx_); lazy_values_.indices.push_back(idx); - goal_reached_on_calling_thread_ = true; + } + if (new_count == needed_count_) { + if (id != threads::get_self_id()) { + threads::set_thread_state(id, threads::pending); + } else { + goal_reached_on_calling_thread_ = true; + } } } } diff --git a/tests/unit/lcos/CMakeLists.txt b/tests/unit/lcos/CMakeLists.txt index 7f919bad8e28..b7839b13b6cb 100644 --- a/tests/unit/lcos/CMakeLists.txt +++ b/tests/unit/lcos/CMakeLists.txt @@ -36,6 +36,9 @@ set(tests reduce shared_future unwrapped + when_all + when_any + when_some ) set(apply_colocated_PARAMETERS LOCALITIES 2) diff --git a/tests/unit/lcos/future.cpp b/tests/unit/lcos/future.cpp index 0c2b27b781f5..41747277cc64 100644 --- a/tests/unit/lcos/future.cpp +++ b/tests/unit/lcos/future.cpp @@ -535,931 +535,6 @@ void test_destroying_a_packaged_task_stores_broken_task() } } -/////////////////////////////////////////////////////////////////////////////// -int make_int_slowly() -{ - hpx::this_thread::sleep_for(boost::chrono::milliseconds(100)); - return 42; -} - -void test_wait_for_either_of_two_futures_1() -{ - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1(pt1.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - - pt1(); - - hpx::lcos::future - , hpx::lcos::future > > > r = - hpx::when_any(f1, f2); - hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future > t = r.get().futures; - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - - HPX_TEST(hpx::util::get<0>(t).is_ready()); - HPX_TEST_EQ(hpx::util::get<0>(t).get(), 42); -} - -void test_wait_for_either_of_two_futures_2() -{ - hpx::lcos::local::packaged_task pt(make_int_slowly); - hpx::lcos::future f1(pt.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - - pt2(); - - hpx::lcos::future - , hpx::lcos::future > > > r = - hpx::when_any(f1, f2); - hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future > t = r.get().futures; - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - - HPX_TEST(hpx::util::get<1>(t).is_ready()); - HPX_TEST_EQ(hpx::util::get<1>(t).get(), 42); -} - -void test_wait_for_either_of_two_futures_list_1() -{ - std::vector > futures; - hpx::lcos::local::packaged_task pt1(make_int_slowly); - futures.push_back(pt1.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - futures.push_back(pt2.get_future()); - - pt1(); - - hpx::lcos::future > > > r = - hpx::when_any(futures); - hpx::when_any_result< - std::vector > > raw = r.get(); - - HPX_TEST_EQ(raw.index, 0u); - - std::vector > t = std::move(raw.futures); - - HPX_TEST(!futures[0].valid()); - HPX_TEST(!futures[1].valid()); - - HPX_TEST(t[0].is_ready()); - HPX_TEST_EQ(t[0].get(), 42); -} - -void test_wait_for_either_of_two_futures_list_2() -{ - std::vector > futures; - hpx::lcos::local::packaged_task pt1(make_int_slowly); - futures.push_back(pt1.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - futures.push_back(pt2.get_future()); - - pt2(); - - hpx::lcos::future > > > r = - hpx::when_any(futures); - hpx::when_any_result< - std::vector > > raw = r.get(); - - HPX_TEST_EQ(raw.index, 1u); - - std::vector > t = std::move(raw.futures); - - HPX_TEST(!futures[0].valid()); - HPX_TEST(!futures[1].valid()); - - HPX_TEST(t[1].is_ready()); - HPX_TEST_EQ(t[1].get(), 42); -} - -void test_wait_for_either_of_three_futures_1() -{ - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1(pt1.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3(pt3.get_future()); - - pt1(); - - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > > > r = - hpx::when_any(f1, f2, f3); - hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > t = r.get().futures; - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - - HPX_TEST(hpx::util::get<0>(t).is_ready()); - HPX_TEST_EQ(hpx::util::get<0>(t).get(), 42); -} - -void test_wait_for_either_of_three_futures_2() -{ - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1(pt1.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3(pt3.get_future()); - - pt2(); - - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > > > r = - hpx::when_any(f1, f2, f3); - hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > t = r.get().futures; - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - - HPX_TEST(hpx::util::get<1>(t).is_ready()); - HPX_TEST_EQ(hpx::util::get<1>(t).get(), 42); -} - -void test_wait_for_either_of_three_futures_3() -{ - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1(pt1.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3(pt3.get_future()); - - pt3(); - - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > > > r = - hpx::when_any(f1, f2, f3); - hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > t = r.get().futures; - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - - HPX_TEST(hpx::util::get<2>(t).is_ready()); - HPX_TEST_EQ(hpx::util::get<2>(t).get(), 42); -} - -void test_wait_for_either_of_four_futures_1() -{ - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1(pt1.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3(pt3.get_future()); - hpx::lcos::local::packaged_task pt4(make_int_slowly); - hpx::lcos::future f4(pt4.get_future()); - - pt1(); - - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > > > r = - hpx::when_any(f1, f2, f3, f4); - hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > t = r.get().futures; - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - HPX_TEST(!f4.valid()); - - HPX_TEST(hpx::util::get<0>(t).is_ready()); - HPX_TEST_EQ(hpx::util::get<0>(t).get(), 42); -} - -void test_wait_for_either_of_four_futures_2() -{ - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1(pt1.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3(pt3.get_future()); - hpx::lcos::local::packaged_task pt4(make_int_slowly); - hpx::lcos::future f4(pt4.get_future()); - - pt2(); - - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > > > r = - hpx::when_any(f1, f2, f3, f4); - hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > t = r.get().futures; - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - HPX_TEST(!f4.valid()); - - HPX_TEST(hpx::util::get<1>(t).is_ready()); - HPX_TEST_EQ(hpx::util::get<1>(t).get(), 42); -} - -void test_wait_for_either_of_four_futures_3() -{ - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1(pt1.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3(pt3.get_future()); - hpx::lcos::local::packaged_task pt4(make_int_slowly); - hpx::lcos::future f4(pt4.get_future()); - - pt3(); - - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > > > r = - hpx::when_any(f1, f2, f3, f4); - hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > t = r.get().futures; - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - HPX_TEST(!f4.valid()); - - HPX_TEST(hpx::util::get<2>(t).is_ready()); - HPX_TEST_EQ(hpx::util::get<2>(t).get(), 42); -} - -void test_wait_for_either_of_four_futures_4() -{ - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1(pt1.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3(pt3.get_future()); - hpx::lcos::local::packaged_task pt4(make_int_slowly); - hpx::lcos::future f4(pt4.get_future()); - - pt4(); - - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > > > r = - hpx::when_any(f1, f2, f3, f4); - hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > t = r.get().futures; - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - HPX_TEST(!f4.valid()); - - HPX_TEST(hpx::util::get<3>(t).is_ready()); - HPX_TEST_EQ(hpx::util::get<3>(t).get(), 42); -} - -void test_wait_for_either_of_five_futures_1_from_list() -{ - std::vector > futures; - - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1(pt1.get_future()); - futures.push_back(boost::move(f1)); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - futures.push_back(boost::move(f2)); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3(pt3.get_future()); - futures.push_back(boost::move(f3)); - hpx::lcos::local::packaged_task pt4(make_int_slowly); - hpx::lcos::future f4(pt4.get_future()); - futures.push_back(boost::move(f4)); - hpx::lcos::local::packaged_task pt5(make_int_slowly); - hpx::lcos::future f5(pt5.get_future()); - futures.push_back(boost::move(f5)); - - pt1(); - - hpx::lcos::future > > > r = - hpx::when_any(futures); - hpx::when_any_result< - std::vector > > raw = r.get(); - - HPX_TEST_EQ(raw.index, 0u); - - std::vector > t = std::move(raw.futures); - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - HPX_TEST(!f4.valid()); - HPX_TEST(!f5.valid()); - - HPX_TEST(t[0].is_ready()); - HPX_TEST_EQ(t[0].get(), 42); -} - -void test_wait_for_either_of_five_futures_1_from_list_iterators() -{ - std::vector > futures; - - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1(pt1.get_future()); - futures.push_back(boost::move(f1)); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - futures.push_back(boost::move(f2)); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3(pt3.get_future()); - futures.push_back(boost::move(f3)); - hpx::lcos::local::packaged_task pt4(make_int_slowly); - hpx::lcos::future f4(pt4.get_future()); - futures.push_back(boost::move(f4)); - hpx::lcos::local::packaged_task pt5(make_int_slowly); - hpx::lcos::future f5(pt5.get_future()); - futures.push_back(boost::move(f5)); - - pt1(); - - hpx::lcos::future > > > r = - hpx::when_any(futures.begin(), futures.end()); - hpx::when_any_result< - std::vector > > raw = r.get(); - - HPX_TEST_EQ(raw.index, 0u); - - std::vector > t = std::move(raw.futures); - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - HPX_TEST(!f4.valid()); - HPX_TEST(!f5.valid()); - - HPX_TEST(t[0].is_ready()); - HPX_TEST_EQ(t[0].get(), 42); -} - -void test_wait_for_either_of_five_futures_1() -{ - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1(pt1.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3(pt3.get_future()); - hpx::lcos::local::packaged_task pt4(make_int_slowly); - hpx::lcos::future f4(pt4.get_future()); - hpx::lcos::local::packaged_task pt5(make_int_slowly); - hpx::lcos::future f5(pt5.get_future()); - - pt1(); - - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > > > r = - hpx::when_any(f1, f2, f3, f4, f5); - hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > t = r.get().futures; - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - HPX_TEST(!f4.valid()); - HPX_TEST(!f5.valid()); - - HPX_TEST(hpx::util::get<0>(t).is_ready()); - HPX_TEST_EQ(hpx::util::get<0>(t).get(), 42); -} - -void test_wait_for_either_of_five_futures_2() -{ - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1(pt1.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3(pt3.get_future()); - hpx::lcos::local::packaged_task pt4(make_int_slowly); - hpx::lcos::future f4(pt4.get_future()); - hpx::lcos::local::packaged_task pt5(make_int_slowly); - hpx::lcos::future f5(pt5.get_future()); - - pt2(); - - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > > > r = - hpx::when_any(f1, f2, f3, f4, f5); - hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > t = r.get().futures; - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - HPX_TEST(!f4.valid()); - HPX_TEST(!f5.valid()); - - HPX_TEST(hpx::util::get<1>(t).is_ready()); - HPX_TEST_EQ(hpx::util::get<1>(t).get(), 42); -} - -void test_wait_for_either_of_five_futures_3() -{ - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1(pt1.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3(pt3.get_future()); - hpx::lcos::local::packaged_task pt4(make_int_slowly); - hpx::lcos::future f4(pt4.get_future()); - hpx::lcos::local::packaged_task pt5(make_int_slowly); - hpx::lcos::future f5(pt5.get_future()); - - pt3(); - - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > > > r = - hpx::when_any(f1, f2, f3, f4, f5); - hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > t = r.get().futures; - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - HPX_TEST(!f4.valid()); - HPX_TEST(!f5.valid()); - - HPX_TEST(hpx::util::get<2>(t).is_ready()); - HPX_TEST_EQ(hpx::util::get<2>(t).get(), 42); -} - -void test_wait_for_either_of_five_futures_4() -{ - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1(pt1.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3(pt3.get_future()); - hpx::lcos::local::packaged_task pt4(make_int_slowly); - hpx::lcos::future f4(pt4.get_future()); - hpx::lcos::local::packaged_task pt5(make_int_slowly); - hpx::lcos::future f5(pt5.get_future()); - - pt4(); - - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > > > r = - hpx::when_any(f1, f2, f3, f4, f5); - hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > t = r.get().futures; - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - HPX_TEST(!f4.valid()); - HPX_TEST(!f5.valid()); - - HPX_TEST(hpx::util::get<3>(t).is_ready()); - HPX_TEST_EQ(hpx::util::get<3>(t).get(), 42); -} - -void test_wait_for_either_of_five_futures_5() -{ - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1(pt1.get_future()); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2(pt2.get_future()); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3(pt3.get_future()); - hpx::lcos::local::packaged_task pt4(make_int_slowly); - hpx::lcos::future f4(pt4.get_future()); - hpx::lcos::local::packaged_task pt5(make_int_slowly); - hpx::lcos::future f5(pt5.get_future()); - - pt5(); - - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > > > r = - hpx::when_any(f1, f2, f3, f4, f5); - hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > t = r.get().futures; - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - HPX_TEST(!f4.valid()); - HPX_TEST(!f5.valid()); - - HPX_TEST(hpx::util::get<4>(t).is_ready()); - HPX_TEST_EQ(hpx::util::get<4>(t).get(), 42); -} - -/////////////////////////////////////////////////////////////////////////////// -// void test_wait_for_either_invokes_callbacks() -// { -// callback_called = 0; -// hpx::lcos::local::packaged_task pt1(make_int_slowly); -// hpx::lcos::future fi = pt1.get_future(); -// hpx::lcos::local::packaged_task pt2(make_int_slowly); -// hpx::lcos::future fi2 = pt2.get_future(); -// pt1.set_wait_callback(wait_callback_for_task); -// -// hpx::thread t(boost::move(pt)); -// -// boost::wait_for_any(fi, fi2); -// HPX_TEST_EQ(callback_called, 1U); -// HPX_TEST_EQ(fi.get(), 42); -// } - -// void test_wait_for_any_from_range() -// { -// unsigned const count = 10; -// for(unsigned i = 0; i < count; ++i) -// { -// hpx::lcos::local::packaged_task tasks[count]; -// hpx::lcos::future futures[count]; -// for(unsigned j = 0; j < count; ++j) -// { -// tasks[j] = boost::move(hpx::lcos::local::packaged_task(make_int_slowly)); -// futures[j] = tasks[j].get_future(); -// } -// hpx::thread t(boost::move(tasks[i])); -// -// hpx::lcos::wait_any(futures, futures); -// -// hpx::lcos::future* const future = boost::wait_for_any(futures, futures+count); -// -// HPX_TEST(future == (futures + i)); -// for(unsigned j = 0; j < count; ++j) -// { -// if (j != i) -// { -// HPX_TEST(!futures[j].is_ready()); -// } -// else -// { -// HPX_TEST(futures[j].is_ready()); -// } -// } -// HPX_TEST_EQ(futures[i].get(), 42); -// } -// } - -void test_wait_for_all_from_list() -{ - unsigned const count = 10; - std::vector > futures; - for (unsigned j = 0; j < count; ++j) - { - hpx::lcos::local::futures_factory task(make_int_slowly); - futures.push_back(task.get_future()); - task.apply(); - } - - hpx::lcos::future > > r = - hpx::when_all(futures); - - std::vector > result = r.get(); - - HPX_TEST_EQ(futures.size(), result.size()); - for (unsigned j = 0; j < count; ++j) - { - HPX_TEST(!futures[j].valid()); - HPX_TEST(result[j].is_ready()); - } -} - -void test_wait_for_all_from_list_iterators() -{ - unsigned const count = 10; - std::vector > futures; - for (unsigned j = 0; j < count; ++j) - { - hpx::lcos::local::futures_factory task(make_int_slowly); - futures.push_back(task.get_future()); - task.apply(); - } - - hpx::lcos::future > > r = - hpx::when_all(futures.begin(), futures.end()); - - std::vector > result = r.get(); - - HPX_TEST_EQ(futures.size(), result.size()); - for (unsigned j = 0; j < count; ++j) - { - HPX_TEST(!futures[j].valid()); - HPX_TEST(result[j].is_ready()); - } -} - -void test_wait_for_all_two_futures() -{ - hpx::lcos::local::futures_factory pt1(make_int_slowly); - hpx::lcos::future f1 = pt1.get_future(); - pt1.apply(); - hpx::lcos::local::futures_factory pt2(make_int_slowly); - hpx::lcos::future f2 = pt2.get_future(); - pt2.apply(); - - typedef hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future > result_type; - hpx::lcos::future r = - hpx::when_all(f1, f2); - - result_type result = r.get(); - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - - HPX_TEST(hpx::util::get<0>(result).is_ready()); - HPX_TEST(hpx::util::get<1>(result).is_ready()); -} - -void test_wait_for_all_three_futures() -{ - hpx::lcos::local::futures_factory pt1(make_int_slowly); - hpx::lcos::future f1 = pt1.get_future(); - pt1.apply(); - hpx::lcos::local::futures_factory pt2(make_int_slowly); - hpx::lcos::future f2 = pt2.get_future(); - pt2.apply(); - hpx::lcos::local::futures_factory pt3(make_int_slowly); - hpx::lcos::future f3 = pt3.get_future(); - pt3.apply(); - - typedef hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > result_type; - hpx::lcos::future r = - hpx::when_all(f1, f2, f3); - - result_type result = r.get(); - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - - HPX_TEST(hpx::util::get<0>(result).is_ready()); - HPX_TEST(hpx::util::get<1>(result).is_ready()); - HPX_TEST(hpx::util::get<2>(result).is_ready()); -} - -void test_wait_for_all_four_futures() -{ - hpx::lcos::local::futures_factory pt1(make_int_slowly); - hpx::lcos::future f1 = pt1.get_future(); - pt1.apply(); - hpx::lcos::local::futures_factory pt2(make_int_slowly); - hpx::lcos::future f2 = pt2.get_future(); - pt2.apply(); - hpx::lcos::local::futures_factory pt3(make_int_slowly); - hpx::lcos::future f3 = pt3.get_future(); - pt3.apply(); - hpx::lcos::local::futures_factory pt4(make_int_slowly); - hpx::lcos::future f4 = pt4.get_future(); - pt4.apply(); - - typedef hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > result_type; - hpx::lcos::future r = - hpx::when_all(f1, f2, f3, f4); - - result_type result = r.get(); - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - HPX_TEST(!f4.valid()); - - HPX_TEST(hpx::util::get<0>(result).is_ready()); - HPX_TEST(hpx::util::get<1>(result).is_ready()); - HPX_TEST(hpx::util::get<2>(result).is_ready()); - HPX_TEST(hpx::util::get<3>(result).is_ready()); -} - -void test_wait_for_all_five_futures() -{ - hpx::lcos::local::futures_factory pt1(make_int_slowly); - hpx::lcos::future f1 = pt1.get_future(); - pt1.apply(); - hpx::lcos::local::futures_factory pt2(make_int_slowly); - hpx::lcos::future f2 = pt2.get_future(); - pt2.apply(); - hpx::lcos::local::futures_factory pt3(make_int_slowly); - hpx::lcos::future f3 = pt3.get_future(); - pt3.apply(); - hpx::lcos::local::futures_factory pt4(make_int_slowly); - hpx::lcos::future f4 = pt4.get_future(); - pt4.apply(); - hpx::lcos::local::futures_factory pt5(make_int_slowly); - hpx::lcos::future f5 = pt5.get_future(); - pt5.apply(); - - typedef hpx::util::tuple< - hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > result_type; - hpx::lcos::future r = - hpx::when_all(f1, f2, f3, f4, f5); - - result_type result = r.get(); - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - HPX_TEST(!f4.valid()); - HPX_TEST(!f5.valid()); - - HPX_TEST(hpx::util::get<0>(result).is_ready()); - HPX_TEST(hpx::util::get<1>(result).is_ready()); - HPX_TEST(hpx::util::get<2>(result).is_ready()); - HPX_TEST(hpx::util::get<3>(result).is_ready()); - HPX_TEST(hpx::util::get<4>(result).is_ready()); -} - -void test_wait_for_two_out_of_five_futures() -{ - unsigned const count = 2; - - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1 = pt1.get_future(); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2 = pt2.get_future(); - pt2(); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3 = pt3.get_future(); - hpx::lcos::local::packaged_task pt4(make_int_slowly); - hpx::lcos::future f4 = pt4.get_future(); - pt4(); - hpx::lcos::local::packaged_task pt5(make_int_slowly); - hpx::lcos::future f5 = pt5.get_future(); - - typedef hpx::when_some_result - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > > result_type; - hpx::lcos::future r = hpx::when_some(count, f1, f2, f3, f4, f5); - - result_type result = r.get(); - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - HPX_TEST(!f4.valid()); - HPX_TEST(!f5.valid()); - - HPX_TEST_EQ(result.indices.size(), count); - HPX_TEST(!hpx::util::get<0>(result.futures).is_ready()); - HPX_TEST(hpx::util::get<1>(result.futures).is_ready()); - HPX_TEST(!hpx::util::get<2>(result.futures).is_ready()); - HPX_TEST(hpx::util::get<3>(result.futures).is_ready()); - HPX_TEST(!hpx::util::get<4>(result.futures).is_ready()); -} - -void test_wait_for_three_out_of_five_futures() -{ - unsigned const count = 3; - - hpx::lcos::local::packaged_task pt1(make_int_slowly); - hpx::lcos::future f1 = pt1.get_future(); - pt1(); - hpx::lcos::local::packaged_task pt2(make_int_slowly); - hpx::lcos::future f2 = pt2.get_future(); - hpx::lcos::local::packaged_task pt3(make_int_slowly); - hpx::lcos::future f3 = pt3.get_future(); - pt3(); - hpx::lcos::local::packaged_task pt4(make_int_slowly); - hpx::lcos::future f4 = pt4.get_future(); - hpx::lcos::local::packaged_task pt5(make_int_slowly); - hpx::lcos::future f5 = pt5.get_future(); - pt5(); - - typedef hpx::when_some_result - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future - , hpx::lcos::future > > result_type; - hpx::lcos::future r = hpx::when_some(count, f1, f2, f3, f4, f5); - - result_type result = r.get(); - - HPX_TEST(!f1.valid()); - HPX_TEST(!f2.valid()); - HPX_TEST(!f3.valid()); - HPX_TEST(!f4.valid()); - HPX_TEST(!f5.valid()); - - HPX_TEST_EQ(result.indices.size(), count); - HPX_TEST(hpx::util::get<0>(result.futures).is_ready()); - HPX_TEST(!hpx::util::get<1>(result.futures).is_ready()); - HPX_TEST(hpx::util::get<2>(result.futures).is_ready()); - HPX_TEST(!hpx::util::get<3>(result.futures).is_ready()); - HPX_TEST(hpx::util::get<4>(result.futures).is_ready()); -} - /////////////////////////////////////////////////////////////////////////////// using boost::program_options::variables_map; using boost::program_options::options_description; @@ -1491,34 +566,6 @@ int hpx_main(variables_map&) test_packaged_task_can_be_moved(); test_destroying_a_promise_stores_broken_promise(); test_destroying_a_packaged_task_stores_broken_task(); - test_wait_for_either_of_two_futures_1(); - test_wait_for_either_of_two_futures_2(); - test_wait_for_either_of_two_futures_list_1(); - test_wait_for_either_of_two_futures_list_2(); - test_wait_for_either_of_three_futures_1(); - test_wait_for_either_of_three_futures_2(); - test_wait_for_either_of_three_futures_3(); - test_wait_for_either_of_four_futures_1(); - test_wait_for_either_of_four_futures_2(); - test_wait_for_either_of_four_futures_3(); - test_wait_for_either_of_four_futures_4(); - test_wait_for_either_of_five_futures_1_from_list(); - test_wait_for_either_of_five_futures_1_from_list_iterators(); - test_wait_for_either_of_five_futures_1(); - test_wait_for_either_of_five_futures_2(); - test_wait_for_either_of_five_futures_3(); - test_wait_for_either_of_five_futures_4(); - test_wait_for_either_of_five_futures_5(); -// test_wait_for_either_invokes_callbacks(); -// test_wait_for_any_from_range(); - test_wait_for_all_from_list(); - test_wait_for_all_from_list_iterators(); - test_wait_for_all_two_futures(); - test_wait_for_all_three_futures(); - test_wait_for_all_four_futures(); - test_wait_for_all_five_futures(); - test_wait_for_two_out_of_five_futures(); - test_wait_for_three_out_of_five_futures(); } hpx::finalize(); diff --git a/tests/unit/lcos/when_all.cpp b/tests/unit/lcos/when_all.cpp new file mode 100644 index 000000000000..e1e0428de3df --- /dev/null +++ b/tests/unit/lcos/when_all.cpp @@ -0,0 +1,268 @@ +// Copyright (C) 2012 Hartmut Kaiser +// (C) Copyright 2008-10 Anthony Williams +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +int make_int_slowly() +{ + hpx::this_thread::sleep_for(boost::chrono::milliseconds(100)); + return 42; +} + +void test_wait_for_all_from_list() +{ + unsigned const count = 10; + std::vector > futures; + for (unsigned j = 0; j < count; ++j) + { + hpx::lcos::local::futures_factory task(make_int_slowly); + futures.push_back(task.get_future()); + task.apply(); + } + + hpx::lcos::future > > r = + hpx::when_all(futures); + + std::vector > result = r.get(); + + HPX_TEST_EQ(futures.size(), result.size()); + for (unsigned j = 0; j < count; ++j) + { + HPX_TEST(!futures[j].valid()); + HPX_TEST(result[j].is_ready()); + } +} + +void test_wait_for_all_from_list_iterators() +{ + unsigned const count = 10; + std::vector > futures; + for (unsigned j = 0; j < count; ++j) + { + hpx::lcos::local::futures_factory task(make_int_slowly); + futures.push_back(task.get_future()); + task.apply(); + } + + hpx::lcos::future > > r = + hpx::when_all(futures.begin(), futures.end()); + + std::vector > result = r.get(); + + HPX_TEST_EQ(futures.size(), result.size()); + for (unsigned j = 0; j < count; ++j) + { + HPX_TEST(!futures[j].valid()); + HPX_TEST(result[j].is_ready()); + } +} + +void test_wait_for_all_two_futures() +{ + hpx::lcos::local::futures_factory pt1(make_int_slowly); + hpx::lcos::future f1 = pt1.get_future(); + pt1.apply(); + hpx::lcos::local::futures_factory pt2(make_int_slowly); + hpx::lcos::future f2 = pt2.get_future(); + pt2.apply(); + + typedef hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future > result_type; + hpx::lcos::future r = + hpx::when_all(f1, f2); + + result_type result = r.get(); + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + + HPX_TEST(hpx::util::get<0>(result).is_ready()); + HPX_TEST(hpx::util::get<1>(result).is_ready()); +} + +void test_wait_for_all_three_futures() +{ + hpx::lcos::local::futures_factory pt1(make_int_slowly); + hpx::lcos::future f1 = pt1.get_future(); + pt1.apply(); + hpx::lcos::local::futures_factory pt2(make_int_slowly); + hpx::lcos::future f2 = pt2.get_future(); + pt2.apply(); + hpx::lcos::local::futures_factory pt3(make_int_slowly); + hpx::lcos::future f3 = pt3.get_future(); + pt3.apply(); + + typedef hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > result_type; + hpx::lcos::future r = + hpx::when_all(f1, f2, f3); + + result_type result = r.get(); + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + + HPX_TEST(hpx::util::get<0>(result).is_ready()); + HPX_TEST(hpx::util::get<1>(result).is_ready()); + HPX_TEST(hpx::util::get<2>(result).is_ready()); +} + +void test_wait_for_all_four_futures() +{ + hpx::lcos::local::futures_factory pt1(make_int_slowly); + hpx::lcos::future f1 = pt1.get_future(); + pt1.apply(); + hpx::lcos::local::futures_factory pt2(make_int_slowly); + hpx::lcos::future f2 = pt2.get_future(); + pt2.apply(); + hpx::lcos::local::futures_factory pt3(make_int_slowly); + hpx::lcos::future f3 = pt3.get_future(); + pt3.apply(); + hpx::lcos::local::futures_factory pt4(make_int_slowly); + hpx::lcos::future f4 = pt4.get_future(); + pt4.apply(); + + typedef hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > result_type; + hpx::lcos::future r = + hpx::when_all(f1, f2, f3, f4); + + result_type result = r.get(); + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + + HPX_TEST(hpx::util::get<0>(result).is_ready()); + HPX_TEST(hpx::util::get<1>(result).is_ready()); + HPX_TEST(hpx::util::get<2>(result).is_ready()); + HPX_TEST(hpx::util::get<3>(result).is_ready()); +} + +void test_wait_for_all_five_futures() +{ + hpx::lcos::local::futures_factory pt1(make_int_slowly); + hpx::lcos::future f1 = pt1.get_future(); + pt1.apply(); + hpx::lcos::local::futures_factory pt2(make_int_slowly); + hpx::lcos::future f2 = pt2.get_future(); + pt2.apply(); + hpx::lcos::local::futures_factory pt3(make_int_slowly); + hpx::lcos::future f3 = pt3.get_future(); + pt3.apply(); + hpx::lcos::local::futures_factory pt4(make_int_slowly); + hpx::lcos::future f4 = pt4.get_future(); + pt4.apply(); + hpx::lcos::local::futures_factory pt5(make_int_slowly); + hpx::lcos::future f5 = pt5.get_future(); + pt5.apply(); + + typedef hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > result_type; + hpx::lcos::future r = + hpx::when_all(f1, f2, f3, f4, f5); + + result_type result = r.get(); + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + HPX_TEST(!f5.valid()); + + HPX_TEST(hpx::util::get<0>(result).is_ready()); + HPX_TEST(hpx::util::get<1>(result).is_ready()); + HPX_TEST(hpx::util::get<2>(result).is_ready()); + HPX_TEST(hpx::util::get<3>(result).is_ready()); + HPX_TEST(hpx::util::get<4>(result).is_ready()); +} + +void test_wait_for_all_late_futures() +{ + hpx::lcos::local::futures_factory pt1(make_int_slowly); + hpx::lcos::future f1 = pt1.get_future(); + pt1.apply(); + hpx::lcos::local::futures_factory pt2(make_int_slowly); + hpx::lcos::future f2 = pt2.get_future(); + + typedef hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future > result_type; + hpx::lcos::future r = + hpx::when_all(f1, f2); + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + + pt2.apply(); + + result_type result = r.get(); + + HPX_TEST(hpx::util::get<0>(result).is_ready()); + HPX_TEST(hpx::util::get<1>(result).is_ready()); +} + +/////////////////////////////////////////////////////////////////////////////// +using boost::program_options::variables_map; +using boost::program_options::options_description; + +int hpx_main(variables_map&) +{ + { + test_wait_for_all_from_list(); + test_wait_for_all_from_list_iterators(); + test_wait_for_all_two_futures(); + test_wait_for_all_three_futures(); + test_wait_for_all_four_futures(); + test_wait_for_all_five_futures(); + test_wait_for_all_late_futures(); + } + + hpx::finalize(); + return hpx::util::report_errors(); +} + +/////////////////////////////////////////////////////////////////////////////// +int main(int argc, char* argv[]) +{ + // Configure application-specific options + options_description cmdline("Usage: " HPX_APPLICATION_STRING " [options]"); + + // We force this test to use several threads by default. + using namespace boost::assign; + std::vector cfg; + cfg += "hpx.os_threads=" + + boost::lexical_cast(hpx::threads::hardware_concurrency()); + + // Initialize and run HPX + return hpx::init(cmdline, argc, argv, cfg); +} + diff --git a/tests/unit/lcos/when_any.cpp b/tests/unit/lcos/when_any.cpp new file mode 100644 index 000000000000..3a19ef9cb69f --- /dev/null +++ b/tests/unit/lcos/when_any.cpp @@ -0,0 +1,758 @@ +// Copyright (C) 2012 Hartmut Kaiser +// (C) Copyright 2008-10 Anthony Williams +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +int make_int_slowly() +{ + hpx::this_thread::sleep_for(boost::chrono::milliseconds(100)); + return 42; +} + +void test_wait_for_either_of_two_futures_1() +{ + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + + pt1(); + + hpx::lcos::future + , hpx::lcos::future > > > r = + hpx::when_any(f1, f2); + hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future > t = r.get().futures; + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + + HPX_TEST(hpx::util::get<0>(t).is_ready()); + HPX_TEST_EQ(hpx::util::get<0>(t).get(), 42); +} + +void test_wait_for_either_of_two_futures_2() +{ + hpx::lcos::local::packaged_task pt(make_int_slowly); + hpx::lcos::future f1(pt.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + + pt2(); + + hpx::lcos::future + , hpx::lcos::future > > > r = + hpx::when_any(f1, f2); + hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future > t = r.get().futures; + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + + HPX_TEST(hpx::util::get<1>(t).is_ready()); + HPX_TEST_EQ(hpx::util::get<1>(t).get(), 42); +} + +void test_wait_for_either_of_two_futures_list_1() +{ + std::vector > futures; + hpx::lcos::local::packaged_task pt1(make_int_slowly); + futures.push_back(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + futures.push_back(pt2.get_future()); + + pt1(); + + hpx::lcos::future > > > r = + hpx::when_any(futures); + hpx::when_any_result< + std::vector > > raw = r.get(); + + HPX_TEST_EQ(raw.index, 0u); + + std::vector > t = std::move(raw.futures); + + HPX_TEST(!futures[0].valid()); + HPX_TEST(!futures[1].valid()); + + HPX_TEST(t[0].is_ready()); + HPX_TEST_EQ(t[0].get(), 42); +} + +void test_wait_for_either_of_two_futures_list_2() +{ + std::vector > futures; + hpx::lcos::local::packaged_task pt1(make_int_slowly); + futures.push_back(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + futures.push_back(pt2.get_future()); + + pt2(); + + hpx::lcos::future > > > r = + hpx::when_any(futures); + hpx::when_any_result< + std::vector > > raw = r.get(); + + HPX_TEST_EQ(raw.index, 1u); + + std::vector > t = std::move(raw.futures); + + HPX_TEST(!futures[0].valid()); + HPX_TEST(!futures[1].valid()); + + HPX_TEST(t[1].is_ready()); + HPX_TEST_EQ(t[1].get(), 42); +} + +void test_wait_for_either_of_three_futures_1() +{ + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3(pt3.get_future()); + + pt1(); + + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > > > r = + hpx::when_any(f1, f2, f3); + hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > t = r.get().futures; + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + + HPX_TEST(hpx::util::get<0>(t).is_ready()); + HPX_TEST_EQ(hpx::util::get<0>(t).get(), 42); +} + +void test_wait_for_either_of_three_futures_2() +{ + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3(pt3.get_future()); + + pt2(); + + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > > > r = + hpx::when_any(f1, f2, f3); + hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > t = r.get().futures; + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + + HPX_TEST(hpx::util::get<1>(t).is_ready()); + HPX_TEST_EQ(hpx::util::get<1>(t).get(), 42); +} + +void test_wait_for_either_of_three_futures_3() +{ + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3(pt3.get_future()); + + pt3(); + + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > > > r = + hpx::when_any(f1, f2, f3); + hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > t = r.get().futures; + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + + HPX_TEST(hpx::util::get<2>(t).is_ready()); + HPX_TEST_EQ(hpx::util::get<2>(t).get(), 42); +} + +void test_wait_for_either_of_four_futures_1() +{ + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3(pt3.get_future()); + hpx::lcos::local::packaged_task pt4(make_int_slowly); + hpx::lcos::future f4(pt4.get_future()); + + pt1(); + + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > > > r = + hpx::when_any(f1, f2, f3, f4); + hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > t = r.get().futures; + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + + HPX_TEST(hpx::util::get<0>(t).is_ready()); + HPX_TEST_EQ(hpx::util::get<0>(t).get(), 42); +} + +void test_wait_for_either_of_four_futures_2() +{ + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3(pt3.get_future()); + hpx::lcos::local::packaged_task pt4(make_int_slowly); + hpx::lcos::future f4(pt4.get_future()); + + pt2(); + + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > > > r = + hpx::when_any(f1, f2, f3, f4); + hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > t = r.get().futures; + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + + HPX_TEST(hpx::util::get<1>(t).is_ready()); + HPX_TEST_EQ(hpx::util::get<1>(t).get(), 42); +} + +void test_wait_for_either_of_four_futures_3() +{ + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3(pt3.get_future()); + hpx::lcos::local::packaged_task pt4(make_int_slowly); + hpx::lcos::future f4(pt4.get_future()); + + pt3(); + + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > > > r = + hpx::when_any(f1, f2, f3, f4); + hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > t = r.get().futures; + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + + HPX_TEST(hpx::util::get<2>(t).is_ready()); + HPX_TEST_EQ(hpx::util::get<2>(t).get(), 42); +} + +void test_wait_for_either_of_four_futures_4() +{ + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3(pt3.get_future()); + hpx::lcos::local::packaged_task pt4(make_int_slowly); + hpx::lcos::future f4(pt4.get_future()); + + pt4(); + + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > > > r = + hpx::when_any(f1, f2, f3, f4); + hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > t = r.get().futures; + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + + HPX_TEST(hpx::util::get<3>(t).is_ready()); + HPX_TEST_EQ(hpx::util::get<3>(t).get(), 42); +} + +void test_wait_for_either_of_five_futures_1_from_list() +{ + std::vector > futures; + + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + futures.push_back(boost::move(f1)); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + futures.push_back(boost::move(f2)); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3(pt3.get_future()); + futures.push_back(boost::move(f3)); + hpx::lcos::local::packaged_task pt4(make_int_slowly); + hpx::lcos::future f4(pt4.get_future()); + futures.push_back(boost::move(f4)); + hpx::lcos::local::packaged_task pt5(make_int_slowly); + hpx::lcos::future f5(pt5.get_future()); + futures.push_back(boost::move(f5)); + + pt1(); + + hpx::lcos::future > > > r = + hpx::when_any(futures); + hpx::when_any_result< + std::vector > > raw = r.get(); + + HPX_TEST_EQ(raw.index, 0u); + + std::vector > t = std::move(raw.futures); + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + HPX_TEST(!f5.valid()); + + HPX_TEST(t[0].is_ready()); + HPX_TEST_EQ(t[0].get(), 42); +} + +void test_wait_for_either_of_five_futures_1_from_list_iterators() +{ + std::vector > futures; + + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + futures.push_back(boost::move(f1)); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + futures.push_back(boost::move(f2)); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3(pt3.get_future()); + futures.push_back(boost::move(f3)); + hpx::lcos::local::packaged_task pt4(make_int_slowly); + hpx::lcos::future f4(pt4.get_future()); + futures.push_back(boost::move(f4)); + hpx::lcos::local::packaged_task pt5(make_int_slowly); + hpx::lcos::future f5(pt5.get_future()); + futures.push_back(boost::move(f5)); + + pt1(); + + hpx::lcos::future > > > r = + hpx::when_any(futures.begin(), futures.end()); + hpx::when_any_result< + std::vector > > raw = r.get(); + + HPX_TEST_EQ(raw.index, 0u); + + std::vector > t = std::move(raw.futures); + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + HPX_TEST(!f5.valid()); + + HPX_TEST(t[0].is_ready()); + HPX_TEST_EQ(t[0].get(), 42); +} + +void test_wait_for_either_of_five_futures_1() +{ + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3(pt3.get_future()); + hpx::lcos::local::packaged_task pt4(make_int_slowly); + hpx::lcos::future f4(pt4.get_future()); + hpx::lcos::local::packaged_task pt5(make_int_slowly); + hpx::lcos::future f5(pt5.get_future()); + + pt1(); + + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > > > r = + hpx::when_any(f1, f2, f3, f4, f5); + hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > t = r.get().futures; + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + HPX_TEST(!f5.valid()); + + HPX_TEST(hpx::util::get<0>(t).is_ready()); + HPX_TEST_EQ(hpx::util::get<0>(t).get(), 42); +} + +void test_wait_for_either_of_five_futures_2() +{ + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3(pt3.get_future()); + hpx::lcos::local::packaged_task pt4(make_int_slowly); + hpx::lcos::future f4(pt4.get_future()); + hpx::lcos::local::packaged_task pt5(make_int_slowly); + hpx::lcos::future f5(pt5.get_future()); + + pt2(); + + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > > > r = + hpx::when_any(f1, f2, f3, f4, f5); + hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > t = r.get().futures; + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + HPX_TEST(!f5.valid()); + + HPX_TEST(hpx::util::get<1>(t).is_ready()); + HPX_TEST_EQ(hpx::util::get<1>(t).get(), 42); +} + +void test_wait_for_either_of_five_futures_3() +{ + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3(pt3.get_future()); + hpx::lcos::local::packaged_task pt4(make_int_slowly); + hpx::lcos::future f4(pt4.get_future()); + hpx::lcos::local::packaged_task pt5(make_int_slowly); + hpx::lcos::future f5(pt5.get_future()); + + pt3(); + + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > > > r = + hpx::when_any(f1, f2, f3, f4, f5); + hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > t = r.get().futures; + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + HPX_TEST(!f5.valid()); + + HPX_TEST(hpx::util::get<2>(t).is_ready()); + HPX_TEST_EQ(hpx::util::get<2>(t).get(), 42); +} + +void test_wait_for_either_of_five_futures_4() +{ + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3(pt3.get_future()); + hpx::lcos::local::packaged_task pt4(make_int_slowly); + hpx::lcos::future f4(pt4.get_future()); + hpx::lcos::local::packaged_task pt5(make_int_slowly); + hpx::lcos::future f5(pt5.get_future()); + + pt4(); + + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > > > r = + hpx::when_any(f1, f2, f3, f4, f5); + hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > t = r.get().futures; + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + HPX_TEST(!f5.valid()); + + HPX_TEST(hpx::util::get<3>(t).is_ready()); + HPX_TEST_EQ(hpx::util::get<3>(t).get(), 42); +} + +void test_wait_for_either_of_five_futures_5() +{ + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3(pt3.get_future()); + hpx::lcos::local::packaged_task pt4(make_int_slowly); + hpx::lcos::future f4(pt4.get_future()); + hpx::lcos::local::packaged_task pt5(make_int_slowly); + hpx::lcos::future f5(pt5.get_future()); + + pt5(); + + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > > > r = + hpx::when_any(f1, f2, f3, f4, f5); + hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > t = r.get().futures; + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + HPX_TEST(!f5.valid()); + + HPX_TEST(hpx::util::get<4>(t).is_ready()); + HPX_TEST_EQ(hpx::util::get<4>(t).get(), 42); +} + +/////////////////////////////////////////////////////////////////////////////// +// void test_wait_for_either_invokes_callbacks() +// { +// callback_called = 0; +// hpx::lcos::local::packaged_task pt1(make_int_slowly); +// hpx::lcos::future fi = pt1.get_future(); +// hpx::lcos::local::packaged_task pt2(make_int_slowly); +// hpx::lcos::future fi2 = pt2.get_future(); +// pt1.set_wait_callback(wait_callback_for_task); +// +// hpx::thread t(boost::move(pt)); +// +// boost::wait_for_any(fi, fi2); +// HPX_TEST_EQ(callback_called, 1U); +// HPX_TEST_EQ(fi.get(), 42); +// } + +// void test_wait_for_any_from_range() +// { +// unsigned const count = 10; +// for(unsigned i = 0; i < count; ++i) +// { +// hpx::lcos::local::packaged_task tasks[count]; +// hpx::lcos::future futures[count]; +// for(unsigned j = 0; j < count; ++j) +// { +// tasks[j] = boost::move(hpx::lcos::local::packaged_task(make_int_slowly)); +// futures[j] = tasks[j].get_future(); +// } +// hpx::thread t(boost::move(tasks[i])); +// +// hpx::lcos::wait_any(futures, futures); +// +// hpx::lcos::future* const future = boost::wait_for_any(futures, futures+count); +// +// HPX_TEST(future == (futures + i)); +// for(unsigned j = 0; j < count; ++j) +// { +// if (j != i) +// { +// HPX_TEST(!futures[j].is_ready()); +// } +// else +// { +// HPX_TEST(futures[j].is_ready()); +// } +// } +// HPX_TEST_EQ(futures[i].get(), 42); +// } +// } + +void test_wait_for_either_of_two_late_futures() +{ + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1(pt1.get_future()); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2(pt2.get_future()); + + hpx::lcos::future + , hpx::lcos::future > > > r = + hpx::when_any(f1, f2); + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + + pt2(); + pt1(); + + hpx::util::tuple< + hpx::lcos::future + , hpx::lcos::future > t = r.get().futures; + + HPX_TEST(hpx::util::get<1>(t).is_ready()); + HPX_TEST_EQ(hpx::util::get<1>(t).get(), 42); +} + +/////////////////////////////////////////////////////////////////////////////// +using boost::program_options::variables_map; +using boost::program_options::options_description; + +int hpx_main(variables_map&) +{ + { + test_wait_for_either_of_two_futures_1(); + test_wait_for_either_of_two_futures_2(); + test_wait_for_either_of_two_futures_list_1(); + test_wait_for_either_of_two_futures_list_2(); + test_wait_for_either_of_three_futures_1(); + test_wait_for_either_of_three_futures_2(); + test_wait_for_either_of_three_futures_3(); + test_wait_for_either_of_four_futures_1(); + test_wait_for_either_of_four_futures_2(); + test_wait_for_either_of_four_futures_3(); + test_wait_for_either_of_four_futures_4(); + test_wait_for_either_of_five_futures_1_from_list(); + test_wait_for_either_of_five_futures_1_from_list_iterators(); + test_wait_for_either_of_five_futures_1(); + test_wait_for_either_of_five_futures_2(); + test_wait_for_either_of_five_futures_3(); + test_wait_for_either_of_five_futures_4(); + test_wait_for_either_of_five_futures_5(); +// test_wait_for_either_invokes_callbacks(); +// test_wait_for_any_from_range(); + test_wait_for_either_of_two_late_futures(); + } + + hpx::finalize(); + return hpx::util::report_errors(); +} + +/////////////////////////////////////////////////////////////////////////////// +int main(int argc, char* argv[]) +{ + // Configure application-specific options + options_description cmdline("Usage: " HPX_APPLICATION_STRING " [options]"); + + // We force this test to use several threads by default. + using namespace boost::assign; + std::vector cfg; + cfg += "hpx.os_threads=" + + boost::lexical_cast(hpx::threads::hardware_concurrency()); + + // Initialize and run HPX + return hpx::init(cmdline, argc, argv, cfg); +} + diff --git a/tests/unit/lcos/when_some.cpp b/tests/unit/lcos/when_some.cpp new file mode 100644 index 000000000000..20accea0884a --- /dev/null +++ b/tests/unit/lcos/when_some.cpp @@ -0,0 +1,184 @@ +// Copyright (C) 2012 Hartmut Kaiser +// (C) Copyright 2008-10 Anthony Williams +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +int make_int_slowly() +{ + hpx::this_thread::sleep_for(boost::chrono::milliseconds(100)); + return 42; +} + +void test_wait_for_two_out_of_five_futures() +{ + unsigned const count = 2; + + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1 = pt1.get_future(); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2 = pt2.get_future(); + pt2(); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3 = pt3.get_future(); + hpx::lcos::local::packaged_task pt4(make_int_slowly); + hpx::lcos::future f4 = pt4.get_future(); + pt4(); + hpx::lcos::local::packaged_task pt5(make_int_slowly); + hpx::lcos::future f5 = pt5.get_future(); + + typedef hpx::when_some_result + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > > result_type; + hpx::lcos::future r = hpx::when_some(count, f1, f2, f3, f4, f5); + + result_type result = r.get(); + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + HPX_TEST(!f5.valid()); + + HPX_TEST_EQ(result.indices.size(), count); + HPX_TEST(!hpx::util::get<0>(result.futures).is_ready()); + HPX_TEST(hpx::util::get<1>(result.futures).is_ready()); + HPX_TEST(!hpx::util::get<2>(result.futures).is_ready()); + HPX_TEST(hpx::util::get<3>(result.futures).is_ready()); + HPX_TEST(!hpx::util::get<4>(result.futures).is_ready()); +} + +void test_wait_for_three_out_of_five_futures() +{ + unsigned const count = 3; + + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1 = pt1.get_future(); + pt1(); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2 = pt2.get_future(); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3 = pt3.get_future(); + pt3(); + hpx::lcos::local::packaged_task pt4(make_int_slowly); + hpx::lcos::future f4 = pt4.get_future(); + hpx::lcos::local::packaged_task pt5(make_int_slowly); + hpx::lcos::future f5 = pt5.get_future(); + pt5(); + + typedef hpx::when_some_result + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > > result_type; + hpx::lcos::future r = hpx::when_some(count, f1, f2, f3, f4, f5); + + result_type result = r.get(); + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + HPX_TEST(!f5.valid()); + + HPX_TEST_EQ(result.indices.size(), count); + HPX_TEST(hpx::util::get<0>(result.futures).is_ready()); + HPX_TEST(!hpx::util::get<1>(result.futures).is_ready()); + HPX_TEST(hpx::util::get<2>(result.futures).is_ready()); + HPX_TEST(!hpx::util::get<3>(result.futures).is_ready()); + HPX_TEST(hpx::util::get<4>(result.futures).is_ready()); +} + +void test_wait_for_two_out_of_five_late_futures() +{ + unsigned const count = 2; + + hpx::lcos::local::packaged_task pt1(make_int_slowly); + hpx::lcos::future f1 = pt1.get_future(); + hpx::lcos::local::packaged_task pt2(make_int_slowly); + hpx::lcos::future f2 = pt2.get_future(); + hpx::lcos::local::packaged_task pt3(make_int_slowly); + hpx::lcos::future f3 = pt3.get_future(); + hpx::lcos::local::packaged_task pt4(make_int_slowly); + hpx::lcos::future f4 = pt4.get_future(); + hpx::lcos::local::packaged_task pt5(make_int_slowly); + hpx::lcos::future f5 = pt5.get_future(); + + typedef hpx::when_some_result + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future + , hpx::lcos::future > > result_type; + hpx::lcos::future r = hpx::when_some(count, f1, f2, f3, f4, f5); + + HPX_TEST(!f1.valid()); + HPX_TEST(!f2.valid()); + HPX_TEST(!f3.valid()); + HPX_TEST(!f4.valid()); + HPX_TEST(!f5.valid()); + + pt2(); + pt4(); + + result_type result = r.get(); + + HPX_TEST_EQ(result.indices.size(), count); + HPX_TEST(!hpx::util::get<0>(result.futures).is_ready()); + HPX_TEST(hpx::util::get<1>(result.futures).is_ready()); + HPX_TEST(!hpx::util::get<2>(result.futures).is_ready()); + HPX_TEST(hpx::util::get<3>(result.futures).is_ready()); + HPX_TEST(!hpx::util::get<4>(result.futures).is_ready()); +} + +/////////////////////////////////////////////////////////////////////////////// +using boost::program_options::variables_map; +using boost::program_options::options_description; + +int hpx_main(variables_map&) +{ + { + test_wait_for_two_out_of_five_futures(); + test_wait_for_three_out_of_five_futures(); + test_wait_for_two_out_of_five_late_futures(); + } + + hpx::finalize(); + return hpx::util::report_errors(); +} + +/////////////////////////////////////////////////////////////////////////////// +int main(int argc, char* argv[]) +{ + // Configure application-specific options + options_description cmdline("Usage: " HPX_APPLICATION_STRING " [options]"); + + // We force this test to use several threads by default. + using namespace boost::assign; + std::vector cfg; + cfg += "hpx.os_threads=" + + boost::lexical_cast(hpx::threads::hardware_concurrency()); + + // Initialize and run HPX + return hpx::init(cmdline, argc, argv, cfg); +} +