test_thread.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // Copyright (C) 2001-2003
  2. // William E. Kempf
  3. // Copyright (C) 2008 Anthony Williams
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. #define BOOST_THREAD_VERSION 2
  8. #define BOOST_THREAD_PROVIDES_INTERRUPTIONS
  9. #include <boost/thread/detail/config.hpp>
  10. #include <boost/thread/thread_only.hpp>
  11. #include <boost/thread/xtime.hpp>
  12. #include <boost/bind.hpp>
  13. #include <boost/ref.hpp>
  14. #include <boost/utility.hpp>
  15. #define BOOST_TEST_MODULE Boost.Threads: thread test suite
  16. #include <boost/test/unit_test.hpp>
  17. #define DEFAULT_EXECUTION_MONITOR_TYPE execution_monitor::use_sleep_only
  18. #include "./util.inl"
  19. int test_value;
  20. void simple_thread()
  21. {
  22. test_value = 999;
  23. }
  24. void comparison_thread(boost::thread::id parent)
  25. {
  26. boost::thread::id const my_id=boost::this_thread::get_id();
  27. BOOST_CHECK(my_id != parent);
  28. boost::thread::id const my_id2=boost::this_thread::get_id();
  29. BOOST_CHECK(my_id == my_id2);
  30. boost::thread::id const no_thread_id=boost::thread::id();
  31. BOOST_CHECK(my_id != no_thread_id);
  32. }
  33. BOOST_AUTO_TEST_CASE(test_sleep)
  34. {
  35. boost::xtime xt = delay(3);
  36. boost::thread::sleep(xt);
  37. // Ensure it's in a range instead of checking actual equality due to time
  38. // lapse
  39. BOOST_CHECK(boost::threads::test::in_range(xt, 2));
  40. }
  41. void do_test_creation()
  42. {
  43. test_value = 0;
  44. boost::thread thrd(&simple_thread);
  45. thrd.join();
  46. BOOST_CHECK_EQUAL(test_value, 999);
  47. }
  48. BOOST_AUTO_TEST_CASE(test_creation)
  49. {
  50. timed_test(&do_test_creation, 1);
  51. }
  52. void do_test_id_comparison()
  53. {
  54. boost::thread::id const self=boost::this_thread::get_id();
  55. boost::thread thrd(boost::bind(&comparison_thread, self));
  56. thrd.join();
  57. }
  58. BOOST_AUTO_TEST_CASE(test_id_comparison)
  59. {
  60. timed_test(&do_test_id_comparison, 1);
  61. }
  62. void interruption_point_thread(boost::mutex* m,bool* failed)
  63. {
  64. boost::unique_lock<boost::mutex> lk(*m);
  65. boost::this_thread::interruption_point();
  66. *failed=true;
  67. }
  68. void do_test_thread_interrupts_at_interruption_point()
  69. {
  70. boost::mutex m;
  71. bool failed=false;
  72. boost::unique_lock<boost::mutex> lk(m);
  73. boost::thread thrd(boost::bind(&interruption_point_thread,&m,&failed));
  74. thrd.interrupt();
  75. lk.unlock();
  76. thrd.join();
  77. BOOST_CHECK(!failed);
  78. }
  79. BOOST_AUTO_TEST_CASE(test_thread_interrupts_at_interruption_point)
  80. {
  81. timed_test(&do_test_thread_interrupts_at_interruption_point, 1);
  82. }
  83. void disabled_interruption_point_thread(boost::mutex* m,bool* failed)
  84. {
  85. boost::unique_lock<boost::mutex> lk(*m);
  86. boost::this_thread::disable_interruption dc;
  87. boost::this_thread::interruption_point();
  88. *failed=false;
  89. }
  90. void do_test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point()
  91. {
  92. boost::mutex m;
  93. bool failed=true;
  94. boost::unique_lock<boost::mutex> lk(m);
  95. boost::thread thrd(boost::bind(&disabled_interruption_point_thread,&m,&failed));
  96. thrd.interrupt();
  97. lk.unlock();
  98. thrd.join();
  99. BOOST_CHECK(!failed);
  100. }
  101. BOOST_AUTO_TEST_CASE(test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point)
  102. {
  103. timed_test(&do_test_thread_no_interrupt_if_interrupts_disabled_at_interruption_point, 1);
  104. }
  105. struct non_copyable_functor:
  106. boost::noncopyable
  107. {
  108. unsigned value;
  109. non_copyable_functor(): boost::noncopyable(),
  110. value(0)
  111. {}
  112. void operator()()
  113. {
  114. value=999;
  115. }
  116. };
  117. void do_test_creation_through_reference_wrapper()
  118. {
  119. non_copyable_functor f;
  120. boost::thread thrd(boost::ref(f));
  121. thrd.join();
  122. BOOST_CHECK_EQUAL(f.value, 999u);
  123. }
  124. BOOST_AUTO_TEST_CASE(test_creation_through_reference_wrapper)
  125. {
  126. timed_test(&do_test_creation_through_reference_wrapper, 1);
  127. }
  128. struct long_running_thread
  129. {
  130. boost::condition_variable cond;
  131. boost::mutex mut;
  132. bool done;
  133. long_running_thread():
  134. done(false)
  135. {}
  136. void operator()()
  137. {
  138. boost::unique_lock<boost::mutex> lk(mut);
  139. while(!done)
  140. {
  141. cond.wait(lk);
  142. }
  143. }
  144. };
  145. void do_test_timed_join()
  146. {
  147. long_running_thread f;
  148. boost::thread thrd(boost::ref(f));
  149. BOOST_CHECK(thrd.joinable());
  150. boost::system_time xt=delay(3);
  151. bool const joined=thrd.timed_join(xt);
  152. BOOST_CHECK(boost::threads::test::in_range(boost::get_xtime(xt), 2));
  153. BOOST_CHECK(!joined);
  154. BOOST_CHECK(thrd.joinable());
  155. {
  156. boost::unique_lock<boost::mutex> lk(f.mut);
  157. f.done=true;
  158. f.cond.notify_one();
  159. }
  160. xt=delay(3);
  161. bool const joined2=thrd.timed_join(xt);
  162. boost::system_time const now=boost::get_system_time();
  163. BOOST_CHECK(xt>now);
  164. BOOST_CHECK(joined2);
  165. BOOST_CHECK(!thrd.joinable());
  166. }
  167. BOOST_AUTO_TEST_CASE(test_timed_join)
  168. {
  169. timed_test(&do_test_timed_join, 10);
  170. }
  171. BOOST_AUTO_TEST_CASE(test_swap)
  172. {
  173. boost::thread t(&simple_thread);
  174. boost::thread t2(&simple_thread);
  175. boost::thread::id id1=t.get_id();
  176. boost::thread::id id2=t2.get_id();
  177. t.swap(t2);
  178. BOOST_CHECK(t.get_id()==id2);
  179. BOOST_CHECK(t2.get_id()==id1);
  180. swap(t,t2);
  181. BOOST_CHECK(t.get_id()==id1);
  182. BOOST_CHECK(t2.get_id()==id2);
  183. }