
My already posted bugfix solves for this, but I am not yet sure what is about the other do_*_lock operations. Are they susceptible to this bug too?
There's a lot of combinations to test here, which is why these issues are going undiagnosed I believe. I needed several other patches similar to your to fix deadlocks with alternate scheduling policies, but when I moved on to a try lock, the old deadlocks came back again, here's a typical example below along with the patches I'm testing so far (someone needs to test timed locks this way as well), John. RCS file: /cvsroot/boost/boost/libs/thread/src/read_write_mutex.cpp,v retrieving revision 1.23 diff -r1.23 read_write_mutex.cpp 487a488,491
if (m_state == 0 && m_num_waking_writers > 0) { adjust_waking.set_adjust(true); // added by RS }
504a509,512
if (m_state == 0 && m_num_waking_writers > 0) { adjust_waking.set_adjust(true); // added by RS }
524a533,536
if (m_state == 0 && m_num_waking_writers > 0) { adjust_waking.set_adjust(true); // added by RS }
#include <iostream> #include <boost/thread/thread.hpp> #include <boost/thread/read_write_mutex.hpp> using namespace boost; // these definitions deadlock try_read_write_mutex guard( read_write_scheduling_policy::alternating_single_read ); typedef try_read_write_mutex::scoped_try_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() { for (long i=0; i< loop_count_for_test; ++i ) { test_lock_type lk( guard, read_write_lock_state::unlocked ); if(0 == lk.try_write_lock()) { std::cout << "try failed" << std::endl; lk.write_lock(); } assert(lk.locked()); long j = ++global_count; lk.demote(); assert(j == global_count); } } int main() { thread_group pool; int number_of_threads = 10; for (int i=0; i < number_of_threads; ++i) { pool.create_thread( do_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; }