
Peter Dimov wrote:
Eric Niebler wrote:
1) a reduction in interface complexity. - one lock class, instead of a scoped_lock, try_lock, timed_lock, etc. - no bools or enums in constructors; instead, there are clearly named factory functions for customizing lock construction.
2) You can initialize a lock in the condition of an "if" statement.
3) You can return a lock from a function. (Benefit is debatable.)
After giving it some thought:
- one lock class: tie;
This seems both popular and reasonable. I presume it would be templated on the mutex type?
- no bools or enums in constructors: there is a bool argument, but it's (in my opinion) acceptable since there is a single constructor, and the argument participates directly in its postcondition:
Lock( Mutex & m, bool l = true ); Post: locked() == l;
No argument here, either. I would mildly prefer a couple more constructors, as you know, but I do see understand your arguments for a single constructor and see the advantages of that design.
- you can return a lock from a function: we can make the locks movable regardless of the interface, so it seems possible to ignore this bullet;
I agree.
- if( lock l = try_lock( m ) ) { }
This is the main difference.
Declarations in conditions are a nice idiom. The typical use is
if( X x = f() ) { // do something with x }
Our example doesn't fit the pattern, however, as the "// do something" part typically does not reference the lock itself.
I don't have much experience with try locks, though. Pretty much the only example that comes to mind is Howard's lock_both:
for(;;) { l1.lock(); if( l2.try_lock() ) return; l1.unlock();
l2.lock(); if( l1.try_lock() ) return; l2.unlock(); }
(I hope I got that right) and I don't see how it can be improved by the if() idiom.
This idiom becomes possible when locks become transferable / returnable anyway, so I don't think we need to worry about it now, either. Mike