
Peter Dimov wrote:
It does what the specification says it does, so it is not "wrong" in this sense. I'm arguing that the specification needs to be changed. ... <snipped> ... The idea of supplying a predicate version is to guard against common user mistakes. For the ordinary wait, the predicate version ignores spurious wakeups. It is very easy to assume that spurious wakeups don't occur and write incorrect code based on this assumption. So we supply a version where they don't.
For timed_wait, there is an additional source of subtle bugs, the fact that a timeout and a signal can both occur and be "delivered" to the same waiting thread. You can't express this in a simple true/false return value, so you have to map the three possible outcomes into two (the fourth outcome is a spurious wakeup and is never returned). I argue that the predicate version should attempt to guard against this additional incorrect user assumption (that only one of a signal occuring or a timeout elapsing happens and not both), too.
To get back to you example,
if (!timed_wait(lk, xt, pred) && !pred()) { // handle timeout }
have you ever seen such code? I haven't.
It doesn't really matter if one of us has seen such code.
if (!timed_wait(lk, xt, pred) ) { // handle timeout }
is the norm (and pred is usually something lambda-ish).
I have no further objections to your proposed change. And I will put this for the next release, as I am uncomfortably to introduce this change in semantics for RC_1_34_0. Also I would like to see yet other opinions on this matter. Do you agree? If yes, it would be very nice if you could file a feature request into source-forge, so that the issue doesn't get lost.
The low-level non-predicate version is available for those that are interested in the "raw" return value from the wait.
I agree, the wary user still has access to all information by using the lower level primitives. Roland