Boost logo

Boost :

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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk