This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug nptl/13165] pthread_cond_wait() can consume a signal that was sent before it started waiting


http://sourceware.org/bugzilla/show_bug.cgi?id=13165

--- Comment #31 from Rich Felker <bugdal at aerifal dot cx> 2012-09-21 08:52:51 UTC ---
Such "speculation" does belong in a bug report so that there is public record
of this behavior of trying to weasel out of conformance requirements. Public
opinion counts, and there should be a cost in public opinion to software
maintainers who refuse to fix bugs and try to argue that their bugs are not
bugs.

Certainly I cannot read your mind to prove claims about your motivation. It
really just boils down to a case of Occam's razor. When fixing the issue would
basically amount to an all-minuses patch that greatly simplifies the code, yet
the maintainers refuse to do it, the simplest explanation is that somebody has
an attachment to the code and the work that went into writing it. If your
motivation is something else, like perhaps concerns about making a mistake and
breaking something in the process of fixing it, why not say that outright
rather than leaving everybody stuck having to speculate about your motivations?
Then the pros and cons of fixing it can be argued rationally. Or do you claim
you have no further motivation here than "I believe the standard allows
low-quality implementations with bad properties like this, so I want to
exercise my right to do a bad job and still claim conformance"?

With the motivation topic out of the way, let's get back to the requirements of
the standard. My understanding is that you claim "the threads that are blocked
on the specified condition variable cond" is a set consisting of at least those
threads which provably (by virtue of the mutex providing ordering) called
pthread_cond_[timed]wait before the caller of pthread_cond_signal obtained the
mutex, but which also may contain other threads. Not, as I originally accused
you of, a completely arbitrary set of other threads, but rather threads which
are "about to" wait on the condition variable in the immediate future after the
signaling thread unlocks the mutex. Is this a correct assessment of your
position?

If so, can you clarify what condition would qualify such threads for membership
in this set? Certainly it can't be any thread that could ever conceivably wait
on the condition variable at any later point in the program flow; if nothing
else, that set is self-referential and thus not even a set (because which
threads are candidates for membership may depend on which thread the signal
unblocked).

My claim that the set of candidate threads pthread_cond_signal can unblock is a
fixed set is based on the following:

1. The status of being blocked on a condition variable is defined only in the
specification of pthread_cond_[timed]wait. I think we both agree on this. There
is no way a thread is ever blocked on a condition variable except by calling
pthread_cond_[timed]wait on it.

2. Sequencing of events between threads is not defined in general, but the use
of mutexes with condition variables imposes a sequencing. In particular, from
the point of view of any other thread, a given thread's status as being blocked
on a condition variable is acquired after it obtains the mutex and before
pthread_cond_[timed]wait releases the mutex. The former sequencing requirement
comes from the fact that you can only call pthread_cond_[timed]wait with the
mutex held, and the fact that pthread_cond_[timed]wait is the function
specified to block; the latter sequencing requirement is the atomicity of
blocking and unlocking the mutex.

3. The pthread_cond_signal function "shall unblock at least one of the threads
that are blocked on the specified condition variable". There is no language
about queuing an unblock request; the language of the standard is "shall
unblock". This means that even if the mechanism is some sort of queued request,
in the sense of the formal, abstract machine, one of the threads in the set of
blocked threads goes from blocked status to unblocked status during the call to
pthread_cond_signal (and, from the stantpoint of observable sequencing, between
the calling thread's calls to pthread_mutex_lock and pthread_mutex_unlock).
Since the mutex is locked during this time, there is no way additional threads
can become blocked on the condition variable. On the other hand, some could
become unblocked due to spurious wakes, so the set could shrink, but it could
not grow.

If you still claim my reasoning is wrong, please cite the specific steps you
believe are hand-waving or misinterpretation of the standard.

-- 
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]