On Sat, Nov 7, 2026 at 11:15 AM Andrea Pinski
<[email protected]> wrote:
>
> On Sat, Nov 7, 2026 at 5:41 AM Rich Felker via Gcc-bugs
> <[email protected]> wrote:
> >
> > On Sat, Nov 07, 2026 at 01:09:03PM +0100, Pepper Gray wrote:
> > > According to POSIX, self-joining a thread is undefined behavior:
> > >
> > > > The behavior is undefined if the value specified by the thread argument 
> > > > to
> > > > pthread_join() refers to the calling thread.
> > >
> > > ```C
> > > #include <pthread.h>
> > > #include <stdio.h>
> > > #include <string.h>
> > >
> > > int main(void) {
> > >   int err = pthread_join(pthread_self(), NULL); // glibc: EDEADLK,
> > > musl: never returns
> > >   printf("returned: %s\n", strerror(err));
> > > }
> > > ```
> > >
> > > but the rationale recommends detecting it:
> > >
> > > > If an implementation detects that the value specified by the thread 
> > > > argument
> > > > to pthread_join() refers to the calling thread, it is recommended that 
> > > > the
> > > > function should fail and report an [EDEADLK] error.
> > >
> > > This is the case in `glibc`, which reports `EDEADLK` while musl just 
> > > hangs.
> > >
> > > While hanging is technically correct, the behavior is undesirable in 
> > > practice,
> > > and a behavior like returning `EDEADLK` or even crashing would make it 
> > > easier to
> > > deal with such an app than when it just hangs.
> >
> > It's very intentional that we do not facilitate forward progress when
> > a program has invoked undefined behavior. There is no good reason to
> > expect that a programmer has ignored the fact that the operation is UB
> > will have taken the effort to check the return value, so just
> > returning an error is likely to result in the flow of execution
> > continuing to run in an inconsistent and possibly dangerous state.
> >
> > Self-join suggests a confusion about who owns resources, so this may
> > involve data races, etc. But this is a pretty broad principle in musl,
> > not specific to pthread_join. At one point my write-up of the
> > principle was included in some glibc guidelines too; I can't find the
> > link to that at the moment, but FWIW there was consensus that "return
> > an error on UB" is bad behavior.
> >
> > > In C++ this case is defined for `std::thread::join()`
> > > ([thread.thread.member](https://eel.is/c++draft/thread.thread.member)):
> > >
> > > > *Throws:* `system_error` when an exception is required 
> > > > ([thread.req.exception]).
> > > >
> > > > *Error conditions:*
> > > > - `resource_deadlock_would_occur` — if deadlock is detected or 
> > > > `get_id() == this_thread::get_id()`.
> > >
> > > However this doesn't work on `libstdc++` nor `libc++` because they both 
> > > wrap
> > > `pthread_join`, which just hangs on musl.
> >
> > If the C++ std::thread::join has a contract to throw on self-join then
> > it needs to call pthread_equal before pthread_join to check that
> > condition.
>
> libstdc++ works correctly:
> ```
>   void
>   thread::join()
>   {
>     int __e = EINVAL;
>
>     if (_M_id != id()) //<< check here

Oh wait that is just checking if the id is invalid or not.  Let me file a bug.

>       __e = __gthread_join(_M_id._M_thread, 0);
>
>     if (__e)
>       __throw_system_error(__e);
>
>     _M_id = id();
>   }
> ```

Reply via email to