1

I am trying to understand to source code of boost shared_mutex, but get stuck in the unlock_shared() method.

Following code copy from boost1.68, line 241 ~ 264:

void unlock_shared()
{
    boost::unique_lock<boost::mutex> lk(state_change);
    state.assert_lock_shared();
    state.unlock_shared();
    if (state.no_shared())
    {
        if (state.upgrade)
        {
            // As there is a thread doing a unlock_upgrade_and_lock that is waiting for state.no_shared()
            // avoid other threads to lock, lock_upgrade or lock_shared, so only this thread is notified.
            state.upgrade=false;
            state.exclusive=true;
            //lk.unlock();
            upgrade_cond.notify_one();
        }
        else
        {
            state.exclusive_waiting_blocked=false;
            //lk.unlock();
        }
        release_waiters();
    }
}

When last reader unlock_shared, if there is an upgrade lock is upgrading, it will set the state.upgrade to false and state.exclusive to true then notify upgrade_cond.

I understand that set state.exclusive to true can avoid other threads to lock, lock_upgrade or lock_shared.

But why set state.upgrade to false? If remove this line, what will happen?

  • 1
    It's *technically* redundant. When `state.exclusive` is `true`, those `can_*` methods in `state_data` already ensures that no one can obtain the mutex before the upgrader, and the upgrader will immediately set `state.upgrade = false` after waking up. However, if you regard it as a state machine, *logically* `upgrade` and `exclusive` can't be `true` at the same time, to maintain the state consistent is important for code modification in the future. – llllllllll Jan 09 '19 at 10:03

0 Answers0