|
Boost : |
From: Max (max3raza_at_[hidden])
Date: 2024-05-15 14:23:57
Hi,
It looks like threads-devel is abandoned I posted here.
I have tried boost::shared_mutex and found an issue. It looks like
it doesn't work as expected.
The problem is following code:
void lock()
{
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
state.exclusive_waiting_blocked=true;
exclusive_cond.wait(lk, boost::bind(&state_data::can_lock,
boost::ref(state)));
state.exclusive=true;
}
On lines:
state.exclusive_waiting_blocked=true;
exclusive_cond.wait(lk, boost::bind(&state_data::can_lock,
boost::ref(state)));
Here the state is changed and new lock_shared() waits because
can_lock_shared returns false in this case. It works as I think it
should be.
The when "old" readers unlocks mutex the last one
unlock_shared() executes
void unlock_shared()
{
...
if (state.no_shared())
{
if (state.upgrade)
{
...
}
else
{
state.exclusive_waiting_blocked=false;
//lk.unlock();
}
release_waiters();
}
where resets state.exclusive_waiting_blocked value.
Then notify 2 condition variables(in release_waiters): 1 for readers
and 1 for writers.
If the writer doesn't win this race and one of the waited readers will be the
first one, the writer runs state_data::can_lock and it of course returns
false.
Then the writer goes to sleep again. But exclusive_waiting_blocked is
still false. So in the high pressure of readers, this writer never
gets a chance to get control in this case anymore until all readers are gone.
This bug was introduced in 1.67 version, before the changes the code was:
while (state.shared_count || state.exclusive)
{
state.exclusive_waiting_blocked=true;
exclusive_cond.wait(lk);
}
but it not the same as (because exclusive_waiting_blocked reassigned):
state.exclusive_waiting_blocked=true;
exclusive_cond.wait(lk, boost::bind(&state_data::can_lock,
boost::ref(state)))
Best Regards,
Maxim
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk