Implementing boost::upgrade_mutex using only standard locks Is this my_upgrade_mutex class a valid implementation of boost::upgrade_mutex semantics? (Ignoring the try_* and *_for/*_until part.)

class my_upgrade_mutex
{
    std::mutex xmutex;
    std::shared_mutex smutex;
public:
    void lock_shared()//u-&gt;s
    {
        smutex.lock_shared();
    }
    void unlock_shared()//s-&gt;u
    {
        smutex.unlock_shared();
    }
    void lock()//u-&gt;x
    {
        xmutex.lock();
        smutex.lock();
    }
    void unlock()//x-&gt;u
    {
        smutex.unlock();
        xmutex.unlock();
    }
    void lock_upgrade()//u-&gt;g
    {
        xmutex.lock();
        smutex.lock_shared();
    }
    void unlock_upgrade()//g-&gt;u
    {
        smutex.unlock_shared();
        xmutex.unlock;
    }
    void unlock_upgrade_and_lock()//g-&gt;x
    {
        smutex.unlock_shared();
        smutex.lock();
    }
    void unlock_and_lock_upgrade()//x-&gt;g
    {
        smutex.unlock();
        smutex.lock_shared();
    }
    void unlock_and_lock_shared()//x-&gt;s
    {
        smutex.unlock();
        smutex.lock_shared()
        xmutex.unlock();
    }
    void unlock_upgrade_and_lock_shared()//g-&gt;s
    {
        xmutex.unlock();
    }
};
I think it actually is valid.

Here's all of the possible states of the two mutexes.

/* u: unlocked, s: shared locked, g: upgrade locked, x: exclusive locked
   (state): of which upgrade_mutex state, the states are as this line
   (inter-state): in the middle of these transitions, the states might be as this line
                  Xab means the original state is of symbol X,
                      and the thread is doing the lock/unlock of a-&gt;b
   symbol xmutex smutex (state) (inter-state)
     A      u      u       u
     B      x      u             Aux Axu Aug Agu Agx Axg Axs Dgu Dgx Exu Exg Exs
     C      u      s       s     Cs
     D      x      s       g     Axs Bs Cux Cug Ds Dgu Dgx Exs
     E      x      x       x
*/



The 10 lock/unlock methods all behave reasonably good in all of the states
Given the prior-method state is in the set, the during-/post-method state is in the set