
Michael Glassford wrote:
Peter Dimov wrote:
[...]
This is certainly possible, but I don't see what the additional complexity buys us.
TryLock l( m, false );
if( l.try_lock() ) { }
looks acceptable to me.
TryLock l( m, non_blocking );
if( l.locked() ) { }
doesn't seem much of an improvement.
The two aren't equivalent (I'm not sure if you meant them to be): in your first example the constructor doesn't attempt to lock, and your second example it attempts a non-blocking lock.
I'm not sure where you think the two examples differ. Both attempt a non-blocking lock.
2) What it buys over your suggestion (at the cost of complexity):
* The ability to specify all applicable lock types (blocking, non-blocking, timed-blocking) in a constructor.
Why is that an improvement?
3) I'm proposing the use of enums rather than bools to indicate the initial state of the lock for these reasons: [...]
OK, let's leave the enum vs bool distinction aside for a while. The crucial difference is explicit try_lock() vs implicit try_lock (a constructor with the appropriate combination of arguments).
4) Which leads to a problem with both your proposal and mine: they both silently break existing code (by changing try_lock(M) from non-blocking to blocking); at least, I presume you meant that. Would eliminating the lock_type(M) constructor (perhaps only for a release or two) be a good idea, or is a prominent warning in the documentation enough?
My proposal (I'm not sure whether I should be credited for it; Howard posted locks that had these properties and I merely commented) can be made to break such code at compile time, simply by removing the nested TryMutex::scoped_try_lock typedef (as there is no longer a need for it, because ::scoped_lock is a TryLock or TimedLock, as appropriate).