Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: pthread_cond_signal/broadcast: necessary to hold mutex?



On Tue, Mar 24, 2026 at 00:46:02 +0100, Tobias Nygren wrote:

> On Mon, 23 Mar 2026 23:23:45 +0100
> Thomas Klausner <wiz%netbsd.org@localhost> wrote:
> 
> > On Mon, Mar 23, 2026 at 10:39:55PM +0100, Tobias Nygren wrote:
> > > On Mon, 23 Mar 2026 21:50:41 +0100
> > > Thomas Klausner <wiz%netbsd.org@localhost> wrote:
> > > 
> > > > - Time for a bug report?
> > > > - Any ideas where this requirement comes from?
> > > 
> > > The hardcopy of "DEC OSF/1 Guide to DECthreads" DEC p/n AA-Q2DPB-TK
> > > printed in 1994 which I happen to still have in my possession states on
> > > page 56 for pthread_cond_wait:
> > > 
> > > ```
> > > Call this routine after you have locked the mutex specified in /mutex/. The results of this routine are unpredictable without first locking the mutex.
> > > ```
> > > 
> > > This predates the first publication of pthreads in IEEE 1003.1c-1995.
> > > The wording strongly suggest that you should lock the mutex but doesn't
> > > explicitly forbid not doing so. I guess POSIX copied those semantics but
> > > made them more clear, as standards people do.
> > > 
> > > I think it would be OK to
> > > s/must be held/must be held for defined behaviour/
> > > in our manpage.
> > 
> > Perhaps I gave too much context.
> > 
> > I'm not talking about the *wait* part, I agree that the mutex needs to
> > be held there.
> > 
> > I was only talking about *signal and *broadcast.
> 
> I see. The historical printed documentation explictly states for
> pthread_cond_signal:
> 
> ```
> You can call this routine regardless if the associated mutex is locked.
> ```
> 
> And for pthread_cond_broadcast:
> 
> ```
> You can call this routine whether the associated mutex is locked or not.
> ```

My knowledge of synchronization primitives is cargo-cultish at best,
and so I tend to defer to Solaris manuals.

"can" above is a vague word.  It probably tells you that the function
itself doesn't touch the mutex and thus the function call itself does
not depend on whether the mutex is locked or not.  So you "can" call
it either way, it won't explode in your face.  Whether the system does
what you expect (or, as POSIX glibly puts it, "if predictable
scheduling behavior is required") is a different matter though.

Solaris "Multithreaded Programming Guide":
  https://docs.oracle.com/cd/E19455-01/806-5257/sync-53686/index.html

  Call pthread_cond_signal() under the protection of the same mutex
  used with the condition variable being signaled.  Otherwise, the
  condition variable could be signaled between the test of the
  associated condition and blocking in pthread_cond_wait(), which can
  cause an infinite wait.


As far as I understand, the above caveat talks about the typical
waiting code that does:

  pthread_mutex_lock(&m);
  {
    while (condition_is_false) {
      //
      // another thread can singal cv here IF it hasn't taken
      // the mutex first, and the wait below will be infinite
      //
      pthread_cond_wait(&cv, &m);
    }
  }
  pthread_mutex_unlock(&m);


I guess POSIX just gives the buggy code a license to survive that
signal-w/out-lock call; and an eager, righteous implementation must
not deny the buggy code its right to live dangerously.

-uwe


Home | Main Index | Thread Index | Old Index