Boost logo

Boost Users :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2008-07-29 12:56:02


On Jul 29, 2008, at 4:57 AM, Vladimir Pozdyaev wrote:

> Howard Hinnant:
>
> > On Jul 28, 2008, at 6:49 AM, Vladimir Pozdyaev wrote:
> > >
> > > Looking at, e.g.,
> > http://www.opengroup.org/onlinepubs/009695399/functions/pthread_cond_init.html
> > > reveals that "It shall be safe to destroy an initialized
> condition
> > > variable upon which no threads are currently blocked." Am I
> right in
> > > understanding that the wait-destroy sequence should be quite safe
> > > this way (provided no one else waits)?
> >
> > I believe your code as shown is subject to "spurious wakeup". If
> the
> > wait ends (spuriously) before the notify_all() completes, or is even
> > initiated, then the notify happens on a destructed cv. POSIX says
> > that in this case the pthread_cond_broadcast will return EINVAL.
>
> I believe I should apologise for this distraction. I am aware of
> possibility of spurious wakeups; they are one reason for the claim
> that the original code is not an example of good practice. The point
> is, spurious wakeups have nothing to do with the problem at hand, so
> I just opted for a more concise code sample.
>
> > The sentence you refer to means that the thread doing the notifying
> > can safely destroy the cv even if the waiting thread has not yet
> > returned from the wait (as long as that thread or any other do not
> try
> > to initiate a new wait after the final signal/broadcast). Note
> though
>
> This is a somewhat narrower interpretation, since the original
> sentence does not consider roles of threads (notifying or waiting).
> Is it a matter of bad wording on the part of the latter? Because I
> don't see in what way does my code contradict the condition "no
> threads are currently blocked" (on a cv). AFAICT, after the only
> cv.wait has finished...
>
> > that it is not safe to destruct the mutex which is being waited on,
> > until the waiting thread wakes from the wait (locking the mutex) and
> > then unlocks that mutex.
>
> ... and the only (scoped) lock on a mutex released, no threads are
> blocked on them, so it shouldn't be problematic to destroy both
> mutex and cv, should it?
>
> (The problem doesn't seem to reproduce with a trunk version of the
> lib, so the point may well be moot anyway, but still I'm wondering...)

For the moment consider that all mutex and cv operations are atomic.
They can not be interrupted (as if they were a single machine
instruction). In this model your code is still not safe. You have a
race: Does the cv get destructed before cv.notify_all() is called?
The answer is that we don't know. If it does, you have undefined
behavior. You would be referencing a member of a destructed object.

Can you construct code that will reliably test your question? Your
current code does not. If your question can not be tested, then the
answer becomes irrelevant.

To be clear, your original code would be just as "correct" if you
commented out the cv.wait(l) in ~C(). Because of spurious wakeups,
this call to wait does not *reliably* have any effect whatsoever.

-Howard


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net