Boost logo

Boost :

From: Michael Glassford (glassfordm_at_[hidden])
Date: 2004-07-15 13:58:58


Christopher Currie wrote:

> Michael Glassford wrote:
>
>> Actually, it has been suggested to eliminate the latter constructor
>> that takes a time as a parameter. There would only be one constructor:
>>
>> scoped_lock(Mutex m&, bool initially_locked=true);
>>
>> which performs a blocking lock. Under this scheme, you would have to
>> write:
>>
>> scoped_lock l(m, false);
>> l.timed_lock(t);
>>
>
> I personally think this makes the interface more complicated, but I
> guess that's a matter of opinion.
> I liken 'lock-on-construction' to
> 'resource-acquisition-is-initialization', but I can see how a timed-lock
> may not precicely model this concept.

Actually, if you've been following the whole discussion, you'll know
that I agree with you. My original intent was to add constructors that
would make it explicit whether you were asking for a blocking lock, a
try lock, or a timed lock, and to remove the ambiguity in the try_lock
constructors (rather arbitrarily, one is blocking, the other
non-blocking, even though they look just like the lock class
constructors which both block). There were some who argued against my
idea and none who supported it, so I dropped the it. I don't know if
this current discussion grew out of that or if it just happened to come
up about the same time; but anyway, it happened.

Having said all that, I should mention that I see the arguments for
simplification, too, and that I prefer either alternative to the way
things are now.

I should also mention that very few of the discussed changes is likely
to be in the upcoming release--the discussion has been too involved and
the time frame is too short. It would be good to get a wider range of
viewpoints, too--the discussion so far has involved too few people, in
my opinion.

>> The main motivation behind the idea of unifying the lock types (and
>> mutex types) is simplification of concepts, I believe.
>
>
> What concerns me is that it feels like the concepts are being loosened.
> By combining the lock concepts, you effective remove the ability to
> demand that a lock always be blocking, regardless of the type of mutex.
> I no longer have the option of saying:

Actually, it has been true all along that (except for constructors) a
try lock is a superset of a plain lock, and a timed lock was nearly a
superset of a try lock. I wanted to (and have in the upcoming release)
made timed lock an actual superset of a try lock by adding a try_lock()
member function to it.

> template <typename mutex_type>
> foo( mutex_type & m )
> {
> mutex_type::scoped_lock l( m );
>
> // do work
>
> l.unlock();
>
> // do more
>
> l.try_lock(); // compile time error?
>
> // still more
> }
>
>
> If the locks are combined, whether this is an error is dependent on if
> the mutex supports a try_lock operation, whereas with the existing
> interface, this is always an error, because I've said up front that I
> only ever want to perform blocking locks here.
>
> I'll also point out that the existing interface supports the opposite
> desire, a compile time error based on mutex_type:
>
> template <typename mutex_type>
> foo( mutex_type & m )
> {
> // compile time error possible
> mutex_type::scoped_try_lock l( m );
>
> // do work
>
> l.unlock();
>
> // do more
>
> l.try_lock(); // ok
>
> // still more
> }
>
>
> This will compile if a TryMutex is passed, but not a plain Mutex,
> because scoped_try_lock is not defined for that type.

Of course this would be true with the single-lock scheme also.

> In the end, I feel that by combining the interfaces, we take away the
> ability of the user to be explicit and restrictive in her use of lock
> types.

So would you advocate removing the lock() method and the blocking lock
constructors from try_lock and timed_lock? I think the three most
consistent designs would be:

1) No overlap between lock, try_lock, and timed_lock.
2) Timed_lock is superset of try_lock, which is a superset of lock.
3) Only one templated lock class that does everything if the mutex
supports it.

The current situation is none of the above.

> My other motivation is an "if it ain't broke, don't fix it"
> attitude; Unless it can be demonstrated that a change in the interface
> is necessary to support needed use cases, we may as well leave well
> enough alone

Thanks for your comments. Some of them represent a viewpoint no one has
expressed yet, which is in my opinion a good thing.

> (and devote time to adding new features :-)).

Then you'll be glad to know that most of my Boost time is being devoted
to adding new features (mostly features at least partially implemented
by the original Boost.Threads author before he stopped working on it).
See http://tinyurl.com/4wdtz (note that it will be slightly out of date
until the page is refreshed).

Mike


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