123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- // Copyright (C) 2001-2003
- // William E. Kempf
- // Copyright (C) 2007 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)
- #define BOOST_THREAD_VERSION 2
- #define BOOST_THREAD_PROVIDES_INTERRUPTIONS
- #define BOOST_TEST_MODULE Boost.Threads: condition test suite
- #include <boost/thread/detail/config.hpp>
- #include <boost/thread/condition.hpp>
- #include <boost/thread/thread_only.hpp>
- #include <boost/thread/xtime.hpp>
- #include <boost/test/unit_test.hpp>
- #include "./util.inl"
- struct condition_test_data
- {
- condition_test_data() : notified(0), awoken(0) { }
- boost::mutex mutex;
- boost::condition_variable condition;
- int notified;
- int awoken;
- };
- void condition_test_thread(condition_test_data* data)
- {
- boost::unique_lock<boost::mutex> lock(data->mutex);
- BOOST_CHECK(lock ? true : false);
- while (!(data->notified > 0))
- data->condition.wait(lock);
- BOOST_CHECK(lock ? true : false);
- data->awoken++;
- }
- struct cond_predicate
- {
- cond_predicate(int& var, int val) : _var(var), _val(val) { }
- bool operator()() { return _var == _val; }
- int& _var;
- int _val;
- private:
- void operator=(cond_predicate&);
- };
- void condition_test_waits(condition_test_data* data)
- {
- boost::unique_lock<boost::mutex> lock(data->mutex);
- BOOST_CHECK(lock ? true : false);
- // Test wait.
- while (data->notified != 1)
- data->condition.wait(lock);
- BOOST_CHECK(lock ? true : false);
- BOOST_CHECK_EQUAL(data->notified, 1);
- data->awoken++;
- data->condition.notify_one();
- // Test predicate wait.
- data->condition.wait(lock, cond_predicate(data->notified, 2));
- BOOST_CHECK(lock ? true : false);
- BOOST_CHECK_EQUAL(data->notified, 2);
- data->awoken++;
- data->condition.notify_one();
- // Test timed_wait.
- boost::xtime xt = delay(10);
- while (data->notified != 3)
- data->condition.timed_wait(lock, xt);
- BOOST_CHECK(lock ? true : false);
- BOOST_CHECK_EQUAL(data->notified, 3);
- data->awoken++;
- data->condition.notify_one();
- // Test predicate timed_wait.
- xt = delay(10);
- cond_predicate pred(data->notified, 4);
- BOOST_CHECK(data->condition.timed_wait(lock, xt, pred));
- BOOST_CHECK(lock ? true : false);
- BOOST_CHECK(pred());
- BOOST_CHECK_EQUAL(data->notified, 4);
- data->awoken++;
- data->condition.notify_one();
- // Test predicate timed_wait with relative timeout
- cond_predicate pred_rel(data->notified, 5);
- BOOST_CHECK(data->condition.timed_wait(lock, boost::posix_time::seconds(10), pred_rel));
- BOOST_CHECK(lock ? true : false);
- BOOST_CHECK(pred_rel());
- BOOST_CHECK_EQUAL(data->notified, 5);
- data->awoken++;
- data->condition.notify_one();
- }
- void do_test_condition_waits()
- {
- condition_test_data data;
- boost::thread thread(bind(&condition_test_waits, &data));
- {
- boost::unique_lock<boost::mutex> lock(data.mutex);
- BOOST_CHECK(lock ? true : false);
- boost::thread::sleep(delay(1));
- data.notified++;
- data.condition.notify_one();
- while (data.awoken != 1)
- data.condition.wait(lock);
- BOOST_CHECK(lock ? true : false);
- BOOST_CHECK_EQUAL(data.awoken, 1);
- boost::thread::sleep(delay(1));
- data.notified++;
- data.condition.notify_one();
- while (data.awoken != 2)
- data.condition.wait(lock);
- BOOST_CHECK(lock ? true : false);
- BOOST_CHECK_EQUAL(data.awoken, 2);
- boost::thread::sleep(delay(1));
- data.notified++;
- data.condition.notify_one();
- while (data.awoken != 3)
- data.condition.wait(lock);
- BOOST_CHECK(lock ? true : false);
- BOOST_CHECK_EQUAL(data.awoken, 3);
- boost::thread::sleep(delay(1));
- data.notified++;
- data.condition.notify_one();
- while (data.awoken != 4)
- data.condition.wait(lock);
- BOOST_CHECK(lock ? true : false);
- BOOST_CHECK_EQUAL(data.awoken, 4);
- boost::thread::sleep(delay(1));
- data.notified++;
- data.condition.notify_one();
- while (data.awoken != 5)
- data.condition.wait(lock);
- BOOST_CHECK(lock ? true : false);
- BOOST_CHECK_EQUAL(data.awoken, 5);
- }
- thread.join();
- BOOST_CHECK_EQUAL(data.awoken, 5);
- }
- BOOST_AUTO_TEST_CASE(test_condition_waits)
- {
- // We should have already tested notify_one here, so
- // a timed test with the default execution_monitor::use_condition
- // should be OK, and gives the fastest performance
- timed_test(&do_test_condition_waits, 12);
- }
- void do_test_condition_wait_is_a_interruption_point()
- {
- condition_test_data data;
- boost::thread thread(bind(&condition_test_thread, &data));
- thread.interrupt();
- thread.join();
- BOOST_CHECK_EQUAL(data.awoken,0);
- }
- BOOST_AUTO_TEST_CASE(test_condition_wait_is_a_interruption_point)
- {
- timed_test(&do_test_condition_wait_is_a_interruption_point, 1);
- }
|