wait_for_pass.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is dual licensed under the MIT and the University of Illinois Open
  6. // Source Licenses. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. // Copyright (C) 2013 Vicente J. Botet Escriba
  10. //
  11. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  12. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  13. // <boost/thread/future.hpp>
  14. // class shared_future<R>
  15. // template <class Rep, class Period>
  16. // future_status
  17. // wait_for(const chrono::duration<Rep, Period>& rel_time) const;
  18. #define BOOST_THREAD_VERSION 4
  19. //#define BOOST_THREAD_USES_LOG
  20. #define BOOST_THREAD_USES_LOG_THREAD_ID
  21. #include <boost/thread/detail/log.hpp>
  22. #include <boost/thread/future.hpp>
  23. #include <boost/thread/thread.hpp>
  24. #include <boost/chrono/chrono_io.hpp>
  25. #include <boost/detail/lightweight_test.hpp>
  26. #include "../../../timming.hpp"
  27. #if defined BOOST_THREAD_USES_CHRONO
  28. #ifdef BOOST_MSVC
  29. #pragma warning(disable: 4127) // conditional expression is constant
  30. #endif
  31. typedef boost::chrono::milliseconds ms;
  32. typedef boost::chrono::nanoseconds ns;
  33. namespace boost
  34. {
  35. template <typename OStream>
  36. OStream& operator<<(OStream& os , boost::future_status st )
  37. {
  38. os << underlying_cast<int>(st) << " ";
  39. return os;
  40. }
  41. template <typename T>
  42. struct wrap
  43. {
  44. wrap(T const& v) :
  45. value(v)
  46. {
  47. }
  48. T value;
  49. };
  50. template <typename T>
  51. exception_ptr make_exception_ptr(T v)
  52. {
  53. return copy_exception(wrap<T> (v));
  54. }
  55. }
  56. void func1(boost::promise<int> p)
  57. {
  58. boost::this_thread::sleep_for(ms(500));
  59. p.set_value(3);
  60. }
  61. int j = 0;
  62. void func3(boost::promise<int&> p)
  63. {
  64. boost::this_thread::sleep_for(ms(500));
  65. j = 5;
  66. p.set_value(j);
  67. }
  68. void func5(boost::promise<void> p)
  69. {
  70. boost::this_thread::sleep_for(ms(500));
  71. p.set_value();
  72. }
  73. const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
  74. int main()
  75. {
  76. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  77. {
  78. typedef boost::chrono::high_resolution_clock Clock;
  79. {
  80. typedef int T;
  81. boost::promise<T> p;
  82. boost::shared_future<T> f((p.get_future()));
  83. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  84. boost::thread(func1, boost::move(p)).detach();
  85. #endif
  86. BOOST_TEST(f.valid());
  87. BOOST_TEST_EQ(f.wait_for(ms(250)) , boost::future_status::timeout);
  88. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  89. #else
  90. func1(boost::move(p));
  91. #endif
  92. BOOST_TEST(f.valid());
  93. BOOST_TEST_EQ(f.wait_for(ms(750)) , boost::future_status::ready);
  94. BOOST_TEST(f.valid());
  95. Clock::time_point t0 = Clock::now();
  96. f.wait();
  97. Clock::time_point t1 = Clock::now();
  98. BOOST_TEST(f.valid());
  99. ns d = t1 - t0;
  100. BOOST_THREAD_TEST_IT(d, ns(max_diff));
  101. }
  102. {
  103. typedef int& T;
  104. boost::promise<T> p;
  105. boost::shared_future<T> f((p.get_future()));
  106. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  107. boost::thread(func3, boost::move(p)).detach();
  108. #endif
  109. BOOST_TEST(f.valid());
  110. BOOST_TEST_EQ(f.wait_for(ms(250)) , boost::future_status::timeout);
  111. BOOST_TEST(f.valid());
  112. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  113. #else
  114. func3(boost::move(p));
  115. #endif
  116. BOOST_TEST_EQ(f.wait_for(ms(750)) , boost::future_status::ready);
  117. BOOST_TEST(f.valid());
  118. Clock::time_point t0 = Clock::now();
  119. f.wait();
  120. Clock::time_point t1 = Clock::now();
  121. BOOST_TEST(f.valid());
  122. ns d = t1 - t0;
  123. BOOST_THREAD_TEST_IT(d, ns(max_diff));
  124. }
  125. {
  126. typedef void T;
  127. boost::promise<T> p;
  128. boost::shared_future<T> f((p.get_future()));
  129. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  130. boost::thread(func5, boost::move(p)).detach();
  131. #endif
  132. BOOST_TEST(f.valid());
  133. BOOST_TEST_EQ(f.wait_for(ms(250)) , boost::future_status::timeout);
  134. BOOST_TEST(f.valid());
  135. #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
  136. #else
  137. func5(boost::move(p));
  138. #endif
  139. BOOST_TEST_EQ(f.wait_for(ms(750)) , boost::future_status::ready);
  140. BOOST_TEST(f.valid());
  141. Clock::time_point t0 = Clock::now();
  142. f.wait();
  143. Clock::time_point t1 = Clock::now();
  144. BOOST_TEST(f.valid());
  145. ns d = t1 - t0;
  146. BOOST_THREAD_TEST_IT(d, ns(max_diff));
  147. }
  148. }
  149. BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
  150. return boost::report_errors();
  151. }
  152. #else
  153. #error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
  154. #endif