Boost logo

Boost :

From: Anthony Williams (anthony_w.geo_at_[hidden])
Date: 2004-07-01 03:51:28


Michael Glassford <glassfordm_at_[hidden]> writes:

> Anthony Williams wrote:
>> Michael Glassford <glassfordm_at_[hidden]> writes:
>>
>>>True. But then, in the reverse case:
>>>
>>> void f(read_write_mutex m)
>>> {
>>> read_write_mutex::write_lock w(m);
>>> if (...)
>>> {
>>> read_write_mutex::read_lock r(w); //lock demotion
>>> //...
>>> }
>>> //Point A
>>> }
>>>
>>>It may not be possible for r's destructor to re-obtain the write lock
>> I don't think this usage should be allowed.
>
> How would it be prevented?

Don't allow a read_lock to be constructed from a write_lock.

>> Once you have a write lock (the "higher class" of lock), then you keep your
>> write lock until you release it. If you want a read lock for the whole
>> time, but only a write lock for a portion of that time, then you write code
>> like the first example. Your "reverse case" actually fulfils that
>> requirement, since there is a portion of the code that only needs a read
>> lock. Therefore it should look like:
>>
>> void f(read_write_mutex m)
>> {
>> read_write_mutex::read_lock r(m); // we need at least a read lock
>> // for everything
>> {
>> read_write_mutex::write_lock w(r);
>> // do stuff that needs the write lock here
>> }
>> if (...)
>> {
>> // we only need the read lock here
>> //...
>> }
>> {
>> read_write_mutex::write_lock w(r);
>> // do more stuff that needs the write lock here
>> }
>> }
>
> Again, this might be a better way to write it, but how do you prevent
> someone from writing it the first way?

See above.

> I think one of the most common use cases for lock demotion would be: obtain
> a write lock and make modifications to a resource; demote to a read lock to
> release other readers and use the resource, making sure that it is still in
> the state it was when we had the write lock (i.e., that no other thread
> obtained a write lock and changed it between the time we released our write
> lock and the time we obtained our read lock).
>
> With a read/write lock, this is expressed in a straightforward way:
>
> void f(read_write_mutex m)
> {
> read_write_mutex::write_lock l(m);
>
> //Modify the resource
>
> l.demote(); //Release other readers
>
> //Use the resource
> }
>
> With the separate read-lock and write-lock, how do you express this in a way
> that is straightforward, doesn't do unnecessary work when the locks are
> released, etc.?

      void f(read_write_mutex m)
      {
          read_write_mutex::read_lock r(m);
          {
              read_write_mutex::write_lock l(r);

              //Modify the resource
          } // release other readers

          //Use the resource
      }

Anthony

-- 
Anthony Williams
Senior Software Engineer, Beran Instruments Ltd.

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