
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