/* Copyright (C) 2002-2025 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
. */
#include
#include "pthreadP.h"
#include
#include
int
___pthread_detach (pthread_t th)
{
struct pthread *pd = (struct pthread *) th;
/* CONCURRENCY NOTES:
Concurrent pthread_detach will return EINVAL for the case the thread
is already detached (THREAD_STATE_DETACHED). POSIX states it is
undefined to call pthread_detach if TH refers to a non joinable thread.
For the case the thread is being terminated (THREAD_STATE_EXITING),
pthread_detach will responsible to clean up the stack. */
unsigned int prevstate = atomic_load_relaxed (&pd->joinstate);
do
{
if (prevstate != THREAD_STATE_JOINABLE)
{
if (prevstate == THREAD_STATE_DETACHED)
return EINVAL;
return __pthread_join (th, 0);
}
}
while (!atomic_compare_exchange_weak_acquire (&pd->joinstate, &prevstate,
THREAD_STATE_DETACHED));
return 0;
}
versioned_symbol (libc, ___pthread_detach, pthread_detach, GLIBC_2_34);
libc_hidden_ver (___pthread_detach, __pthread_detach)
#ifndef SHARED
strong_alias (___pthread_detach, __pthread_detach)
#endif
#if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_34)
compat_symbol (libc, ___pthread_detach, pthread_detach, GLIBC_2_0);
#endif