$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Howard Hinnant (hinnant_at_[hidden])
Date: 2007-11-14 16:41:12
On Nov 14, 2007, at 3:53 PM, Preston A. Elder wrote:
> Is there any plan to implement something like this:
>
> http://www.neuromancy.net/fisheye/browse/mantra/trunk/Mantra-I/mantra/
> utils/shared_mutex_views.h?r=435
>
> So that a shared mutex can be operated like a normal mutex, including
> scoped_lock behavior, and you can choose whether that scoped_lock
> behavior should be to acquire an exclusive, a shared, or an upgrade  
> lock?
>
> The idea being:
>
> // somewhere else
> shared_mutex smtx;
>
> // Where I need it:
>
> shared_mutex_view smv(smtx);
> shared_mutex_view::scoped_lock sl(smv);
> // ...
>
> // OR:
> exclusive_mutex_view smv(smtx);
> exclusive_mutex_view::scoped_lock sl(smv);
>
> Right now, shared_mutex only has primitives, and cannot be used with
> things like scoped_lock (aka. unique_lock).  Additionally, it cannot  
> be
> used as a condition, despite the condition framework.  These views  
> would
> facilitate that, however I'll admit, I've not thought of all the
> implications of such things.
I'm not sure I see the purpose of:
> exclusive_mutex_view smv(smtx);
> exclusive_mutex_view::scoped_lock sl(smv);
because actually unique_lock<shared_mutex> should work just fine (and  
has semantics similar to what you indicate for exclusive_mutex_view).   
And condition_variable_any::wait works with unique_lock<shared_mutex>  
just fine as well.  That covers exclusive locking for shared_mutex.
For shared locking what you have for shared_mutex_view is very similar  
to the shared_lock<Mutex> template proposed here:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2406.html#shared_mutex
Differences include:
shared_mutex_view works only for shared_mutex.  shared_lock works for  
any type supporting the shared_mutex interface (such as a user-written  
interruptible_shared_mutex).
It is easier (syntactically) to convert ownership modes using lock  
conversion syntax.  For example:
upgrade_mutex mut;
unique_lock<upgrade_mutex> lk(mut);
// mut exclusive locked here
shared_lock<upgrade_mutex> slk(move(lk));
// mut share locked here
I.e. the locks provide the "homogenized view", and add the ability to  
move and convert the mutex ownership, also with a homogenized syntax.   
The homogenized syntax for moving and converting mutex ownership  
enables extremely simple implementations of "generic lock conversion  
algorithms" (such as transfer_lock also in N2406).
And all of the lock/mutex combinations work with  
condition_variable_any (which only requires lock/unlock and everything  
has that).
shared_mutex mut;
condition_variable_any cv;
void wait_in_shared_ownership_mode()
{
     shared_lock<shared_mutex> shared_lk(mut);
     // mut is now shared-locked
     // ...
     while (not_ready_to_proceed())
         cv.wait(shared_lk);  // shared-lock released while waiting
     // mut is now shared-locked
     // ...
}   // mut is now unlocked
void wait_in_unique_ownership_mode()
{
     unique_lock<shared_mutex> lk(mut);
     // mut is now unique-locked
     // ...
     while (not_ready_to_proceed())
         cv.wait(lk);  // unique-lock released while waiting
     // mut is now unique-locked
     // ...
}   // mut is now unlocked
upgrade_mutex mut2;
void wait_with_transfer_from_unique_to_shared_ownership()
{
     upgrade_lock<upgrade_mutex> slk(mut2);
     // mut2 is now share-locked
     // ...
     if (I_need_to()) {
         transfer_lock<unique_lock<upgrade_mutex>,  
upgrade_lock<upgrade_mutex>> lk(slk);
         // mut2 is now unique-locked
         // ...
         while (not_ready_to_proceed())
             cv.wait(lk);  // mut2 share-locked while waiting
         // mut2 is now unique-locked
         // ...
     }
     // mut2 is now share-locked
     // ...
}   // mut2 is now unlocked
-Howard