#include #include #include #include #include #include #include #include #define BOOST_TEST_DYN_LINK #define BOOST_TEST_MAIN #define BOOST_AUTO_TEST_MAIN #include #include using std::cout; using std::endl; void post_sem(boost::binary_semaphore* sem, int tout_ms) { cout << "\nwaiting for " << tout_ms << " ms\n" << endl; struct timespec req = {0}; struct timespec rem = {0}; req.tv_sec = tout_ms / 1000; req.tv_nsec = (tout_ms % 1000) * 1000000; int const s = nanosleep(&req, &rem); if (s < 0) { throw std::runtime_error(strerror(errno)); } cout << "\nposting" << endl; sem->post(); } void multiple_posts_two_waits() { typedef boost::binary_semaphore binsem_t; binsem_t sem(1); for (int i = 0; i < 50; ++i) { boost::thread t1(boost::bind(&binsem_t::post, &sem)); boost::thread t2(boost::bind(&binsem_t::post, &sem)); boost::thread t3(boost::bind(&binsem_t::post, &sem)); boost::thread t4(boost::bind(&binsem_t::post, &sem)); boost::thread t5(boost::bind(&binsem_t::post, &sem)); boost::thread t6(boost::bind(&binsem_t::post, &sem)); boost::thread t7(boost::bind(&binsem_t::post, &sem)); t1.join(); t2.join(); t3.join(); t4.join(); t5.join(); t6.join(); t7.join(); } cout << "\nwaiting 1st time\n" << endl; sem.wait(); int const tout_ms = 300; boost::thread t1(boost::bind(post_sem, &sem, tout_ms)); cout << "\nwaiting 2nd time\n" << endl; boost::posix_time::ptime c1 = boost::posix_time::microsec_clock::universal_time(); sem.wait(); boost::posix_time::ptime c2 = boost::posix_time::microsec_clock::universal_time(); cout << "\nresumed" << endl; boost::posix_time::time_duration const c = c2 - c1; cout << "\nc2: " << c2 << ", c1: " << c1 << ", c: " << c << endl; if (c < boost::posix_time::millisec(tout_ms - 150)) { throw std::runtime_error("wait() failed"); } if (c > boost::posix_time::millisec(tout_ms + 150)) { throw std::runtime_error("wait() failed2"); } cout << "\njoining with thread\n" << endl; t1.join(); } BOOST_AUTO_TEST_CASE(multiple_posts_two_waits_loop) { for (int i = 0; i < 1000000; ++i) { multiple_posts_two_waits(); } }