
Batov, Vladimir wrote:
Guys,
Could we please resist complicating interfaces when we do not have to? I personally consider an additional blocking parameter for something like try_lock excessive because it distorts try_lock into becoming scoped_lock. Let's keep different concepts different. Blocking in try_lock is an oxymoron -- try_lock cannot block because it is "try".
Perhaps I would agree, except that try_lock already has a lock() method, which, by design, blocks. To rephrase what Christopher pointed out, a scoped_try_lock is nearly the same as a scoped_lock with try_* methods added (I say nearly because the constructors are different, which is partly what I'm trying to address).
The basic usages (covering about 80%) are:
scoped_lock l(m); // Block until it locks. scoped_try_lock l(m); // Try (!) to lock. I'll check the result. scoped_timed_lock l(m, time); // Block until it locks or time runs out. I'll check the result.
Simple and clean.
True. It's also simple and clean to say that a try_lock is a lock with added functionality, and a timed_lock is a try_lock with added functionality.
The only functionality that I can see beyond that is when I have to only declare a lock but apply it later. Like:
Void Foo() { scoped_lock l(m, do_not_lock);
if (something) { l.lock(); // Can't declare here. ... } } For that purpose we'll need something like
scoped_lock(mutex&, nolock_t);
I'm increasingly liking this syntax, by the way; thanks for suggesting it.
That's it. Isn't it?
Alternatively we might consider making timed_lock our basic lock as scoped_lock and try_lock are merely border-cases (time=infinite and time=0 respectively). Then, scoped_lock and try_lock would be real refinements (convenience interfaces) of that general concept.
Mike