Boost logo

Boost :

From: John Maddock (john_at_[hidden])
Date: 2005-09-03 05:58:13


> 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;
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk