
Michael Glassford wrote:
Actually, if you've been following the whole discussion, you'll know that I agree with you.
My appologies, I lost track of the thread a while back, and haven't had the time to catch up.
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).
I'm on the fence on this issue; since it's been put off until after the next release I won't go into it here.
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.
I would actually prefer that timed_lock *not* be a superset of try_lock. The documented concepts clearly don't imply that, it appears to be an artifact of the implementation. If you happen to want to use try_lock semantics on a timed_lock, it's easy enough to use a zero timeout.
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.
True, it's the first case that doesn't appear to be possible with the single-lock scheme. In otherwords, I want the *lock* to prohibit the try_lock operation, not the mutex.
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.
As it stands, I feel I would advocate this option, at least among constructors, perhaps leaving the lock() method intact. Though I wouldn't cry if it were taken away, because it isn't strictly necessary, just a convenience.
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).
Thanks to you, for picking up the reigns to maintain it. I know you've done a lot of work to ensure that Boost.Threads has not grown stagnant, and matures. Christopher -- Christopher Currie <codemonkey@gmail.com>