// thread_scap.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #include #include #include using namespace boost; // these definitions deadlock timed_read_write_mutex guard( read_write_scheduling_policy::writer_priority ); typedef timed_read_write_mutex::scoped_timed_read_write_lock test_lock_type; // these definitions work as expected // mutex guard; // typedef mutex::scoped_lock test_lock_type; long global_count = 0; long loop_count_for_test = 100000; void do_work() { int fail_count = 0; int success_count = 0; for (long i=0; i< loop_count_for_test; ++i ) { test_lock_type lk( guard, read_write_lock_state::unlocked ); boost::xtime xt; boost::xtime_get(&xt, boost::TIME_UTC); //xt.sec += 1; if(0 == lk.timed_write_lock(xt)) { ++fail_count; lk.write_lock(); } else ++success_count; assert(lk.locked()); long j = ++global_count; lk.demote(); assert(j == global_count); } test_lock_type lk2( guard, read_write_lock_state::unlocked ); lk2.write_lock(); std::cout << fail_count << " try failures and " << success_count << " try successes." << std::endl; } void do_read_work() { int fail_count = 0; int success_count = 0; int total = 0; for (long i=0; i< loop_count_for_test; ++i ) { test_lock_type lk( guard, read_write_lock_state::unlocked ); if(0 == lk.try_read_lock()) { ++fail_count; lk.read_lock(); } else ++success_count; assert(lk.locked()); total += global_count; } test_lock_type lk2( guard, read_write_lock_state::unlocked ); lk2.write_lock(); std::cout << fail_count << " read try failures and " << success_count << " read try successes." << std::endl; } int main() { thread_group pool; int number_of_threads = 20; for (int i=0; i < number_of_threads; ++i) { pool.create_thread( do_work ); } for (int i=0; i < number_of_threads; ++i) { pool.create_thread( do_read_work ); } pool.join_all(); //result check std::cout << "We should get here without a deadlock\n"; std::cout << "global count = " << global_count << "\n"; std::cout << "global count should be = " << loop_count_for_test * number_of_threads << "\n"; return 0; }