
Peter Dimov wrote:
The "unified" timed lock case is
{ scoped_lock l( m, false );
if( l.timed_lock( t ) ) { // do stuff } else { // what do we do here? presumably either:
// setup for unbounded wait l.lock(); // do stuff
// or signal failure } }
I understand this is just an example, but the question I find myself asking is: if a blocking lock is acceptable, why not do it in the first place? However, let's assume that for some performance reason we'd like to see if we can get the lock quickly, and if not, then do the (potentially expensive) setup we need to allow for a blocking lock. The timed_lock class supports the above scenario as-is. And even if it didn't, the behavior could still be done: bool done = false; { scoped_timed_lock l( m, t ); if ( l.locked() ) { // do stuff done = true; } } if ( ! done ) { // setup scoped_lock l( m ); // do stuff } Granted, this may seem a bit more cumbersome to the user, which is why the scoped_timed_lock class has a blocking lock() operation built in.
The scoped_timed_lock use case also needs to eventually contain an if( l ) statement; you can't do much if you don't know whether your timed lock succeeded.
Agreed.
One might also argue that a separate scoped_timed_lock makes accidentally omitting the if() statement more likely and harder to spot.
I can see that, although one could also argue that the name of the scoped_timed_lock class is an immediate signal that one needs to check the status of the lock. It does feel like a matter of preference, though; I prefer to use the locking constructors as opposed to the non-locking constructors. Fortunately, the scoped_timed_lock supports either usage as-is, without modification.
But it's hard to tell without real use cases.
Agreed. -- Christopher Currie <codemonkey@gmail.com>