Boost logo

Boost :

From: Michael Glassford (glassfordm_at_[hidden])
Date: 2004-06-28 18:55:36


Batov, Vladimir wrote:
>>Part of the point, though, is that try_lock doesn't actually work that
>>way: one of the try_lock constructors does a non-blocking try_lock(),
>>and the other does a blocking lock(). Without looking, do you always
>>remember which one does which? I don't.
>
>
> Well, first, the behavior that I was talking about in my prev. email (ones I was happy about) were the 'basic' constructors (that I called 'default' constructors -- what an embarassment). The following is IMHO good and I would not like see them complicated:
>
> 1. scoped_lock l(m); // Blocks until it locks.
> 2. scoped_lock l(m, true); // As above.
> 3. scoped_lock l(m, false); // Only declaration. Does nothing. Needed if I need to declare but use it later.
> 4. try_lock l(m); // Tries to lock. Always falls through. I need to check the result.
> 5. try_lock l(m, false); // Only declaration. Does nothing.
> 6. timed_lock l(m, time); // Blocks until locks or 'time' expires.
> 7. timed_lock l(m, false); // Only declaration. Does nothing.

I can agree with all of these.

> I have to agree that the following behavior
>
> 8. try_lock l(m, true);
> 9. timed_lock l(m, true);
>
> that according to the documentation call lock() instead of respective try_lock() and timed_lock() look wrong.

I'm glad you agree, since this is the most important of the issues I was
trying to address.

> I'd be temted to say that merely making (8) work as (4) would be sufficient fo fix try_lock.

This would be best; unfortunately, this would silently change the
meaning of existing code.

> (9) does not appear "fixable" in a similar way.

Which is one reason I suggested the solution I did (adding an additional
"blocking" parameter).

> I am tempted to suggest something similar to overloaded 'operator new':
>
> struct nolock_t {};
> nolock_t nolock;
>
> 1. scoped_lock l(m);
> 2. scoped_lock l(m, nolock);
> 3. try_lock l(m);
> 4. try_lock l(m, nolock);
> 5. timed_lock l(m, time);
> 6. timed_lock l(m, nolock);
>
> It removes redundancy (as with the original scoped_lock(m) and scoped_lock(m, true)) and makes everything simple and consistent.

I considered something like this, but since I was also working on the
read/write mutex at the time, I was trying to be consistent with that as
well. The read/write mutex has three states, of course; read-clocked,
write-locked, and unlocked, so this parameter uses an enumeration
instead of a bool (or the nolock parameter you suggest above). Of course
the same approach could be used with the read/write lock, and it would
solve the problem of degenerate cases like try_lock(m, false, blocking).

Thanks for your comments; I'll think about this some more.

Mike


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk