[prev in list] [next in list] [prev in thread] [next in thread] 

List:       boost
Subject:    [boost] Fwd: shared_mutex lock() issue
From:       Max via Boost <boost () lists ! boost ! org>
Date:       2024-05-15 14:23:57
Message-ID: CAANpX5gdLzbOOo7anrpeJ+bie4L7grfCg-miG09fUGWQeU6y9A () mail ! gmail ! com
[Download RAW message or body]

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

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic