test_condition.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // Copyright (C) 2001-2003
  2. // William E. Kempf
  3. // Copyright (C) 2007 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. #define BOOST_TEST_MODULE Boost.Threads: condition test suite
  10. #include <boost/thread/detail/config.hpp>
  11. #include <boost/thread/condition.hpp>
  12. #include <boost/thread/thread_only.hpp>
  13. #include <boost/thread/xtime.hpp>
  14. #include <boost/test/unit_test.hpp>
  15. #include "./util.inl"
  16. struct condition_test_data
  17. {
  18. condition_test_data() : notified(0), awoken(0) { }
  19. boost::mutex mutex;
  20. boost::condition_variable condition;
  21. int notified;
  22. int awoken;
  23. };
  24. void condition_test_thread(condition_test_data* data)
  25. {
  26. boost::unique_lock<boost::mutex> lock(data->mutex);
  27. BOOST_CHECK(lock ? true : false);
  28. while (!(data->notified > 0))
  29. data->condition.wait(lock);
  30. BOOST_CHECK(lock ? true : false);
  31. data->awoken++;
  32. }
  33. struct cond_predicate
  34. {
  35. cond_predicate(int& var, int val) : _var(var), _val(val) { }
  36. bool operator()() { return _var == _val; }
  37. int& _var;
  38. int _val;
  39. private:
  40. void operator=(cond_predicate&);
  41. };
  42. void condition_test_waits(condition_test_data* data)
  43. {
  44. boost::unique_lock<boost::mutex> lock(data->mutex);
  45. BOOST_CHECK(lock ? true : false);
  46. // Test wait.
  47. while (data->notified != 1)
  48. data->condition.wait(lock);
  49. BOOST_CHECK(lock ? true : false);
  50. BOOST_CHECK_EQUAL(data->notified, 1);
  51. data->awoken++;
  52. data->condition.notify_one();
  53. // Test predicate wait.
  54. data->condition.wait(lock, cond_predicate(data->notified, 2));
  55. BOOST_CHECK(lock ? true : false);
  56. BOOST_CHECK_EQUAL(data->notified, 2);
  57. data->awoken++;
  58. data->condition.notify_one();
  59. // Test timed_wait.
  60. boost::xtime xt = delay(10);
  61. while (data->notified != 3)
  62. data->condition.timed_wait(lock, xt);
  63. BOOST_CHECK(lock ? true : false);
  64. BOOST_CHECK_EQUAL(data->notified, 3);
  65. data->awoken++;
  66. data->condition.notify_one();
  67. // Test predicate timed_wait.
  68. xt = delay(10);
  69. cond_predicate pred(data->notified, 4);
  70. BOOST_CHECK(data->condition.timed_wait(lock, xt, pred));
  71. BOOST_CHECK(lock ? true : false);
  72. BOOST_CHECK(pred());
  73. BOOST_CHECK_EQUAL(data->notified, 4);
  74. data->awoken++;
  75. data->condition.notify_one();
  76. // Test predicate timed_wait with relative timeout
  77. cond_predicate pred_rel(data->notified, 5);
  78. BOOST_CHECK(data->condition.timed_wait(lock, boost::posix_time::seconds(10), pred_rel));
  79. BOOST_CHECK(lock ? true : false);
  80. BOOST_CHECK(pred_rel());
  81. BOOST_CHECK_EQUAL(data->notified, 5);
  82. data->awoken++;
  83. data->condition.notify_one();
  84. }
  85. void do_test_condition_waits()
  86. {
  87. condition_test_data data;
  88. boost::thread thread(bind(&condition_test_waits, &data));
  89. {
  90. boost::unique_lock<boost::mutex> lock(data.mutex);
  91. BOOST_CHECK(lock ? true : false);
  92. boost::thread::sleep(delay(1));
  93. data.notified++;
  94. data.condition.notify_one();
  95. while (data.awoken != 1)
  96. data.condition.wait(lock);
  97. BOOST_CHECK(lock ? true : false);
  98. BOOST_CHECK_EQUAL(data.awoken, 1);
  99. boost::thread::sleep(delay(1));
  100. data.notified++;
  101. data.condition.notify_one();
  102. while (data.awoken != 2)
  103. data.condition.wait(lock);
  104. BOOST_CHECK(lock ? true : false);
  105. BOOST_CHECK_EQUAL(data.awoken, 2);
  106. boost::thread::sleep(delay(1));
  107. data.notified++;
  108. data.condition.notify_one();
  109. while (data.awoken != 3)
  110. data.condition.wait(lock);
  111. BOOST_CHECK(lock ? true : false);
  112. BOOST_CHECK_EQUAL(data.awoken, 3);
  113. boost::thread::sleep(delay(1));
  114. data.notified++;
  115. data.condition.notify_one();
  116. while (data.awoken != 4)
  117. data.condition.wait(lock);
  118. BOOST_CHECK(lock ? true : false);
  119. BOOST_CHECK_EQUAL(data.awoken, 4);
  120. boost::thread::sleep(delay(1));
  121. data.notified++;
  122. data.condition.notify_one();
  123. while (data.awoken != 5)
  124. data.condition.wait(lock);
  125. BOOST_CHECK(lock ? true : false);
  126. BOOST_CHECK_EQUAL(data.awoken, 5);
  127. }
  128. thread.join();
  129. BOOST_CHECK_EQUAL(data.awoken, 5);
  130. }
  131. BOOST_AUTO_TEST_CASE(test_condition_waits)
  132. {
  133. // We should have already tested notify_one here, so
  134. // a timed test with the default execution_monitor::use_condition
  135. // should be OK, and gives the fastest performance
  136. timed_test(&do_test_condition_waits, 12);
  137. }
  138. void do_test_condition_wait_is_a_interruption_point()
  139. {
  140. condition_test_data data;
  141. boost::thread thread(bind(&condition_test_thread, &data));
  142. thread.interrupt();
  143. thread.join();
  144. BOOST_CHECK_EQUAL(data.awoken,0);
  145. }
  146. BOOST_AUTO_TEST_CASE(test_condition_wait_is_a_interruption_point)
  147. {
  148. timed_test(&do_test_condition_wait_is_a_interruption_point, 1);
  149. }