diff --git a/nptl/pthread_getaffinity.c b/nptl/pthread_getaffinity.c index 0828185fbd..ec5d2dc2cc 100644 --- a/nptl/pthread_getaffinity.c +++ b/nptl/pthread_getaffinity.c @@ -15,25 +15,33 @@ License along with the GNU C Library; if not, see . */ -#include -#include +#include #include -#include -#include -#include -#include #include int __pthread_getaffinity_np (pthread_t th, size_t cpusetsize, cpu_set_t *cpuset) { - const struct pthread *pd = (const struct pthread *) th; + struct pthread *pd = (struct pthread *) th; - int res = INTERNAL_SYSCALL_CALL (sched_getaffinity, pd->tid, - MIN (INT_MAX, cpusetsize), cpuset); - if (INTERNAL_SYSCALL_ERROR_P (res)) - return INTERNAL_SYSCALL_ERRNO (res); + /* Block all signals, as required by pd->exit_lock. */ + internal_sigset_t old_mask; + internal_signal_block_all (&old_mask); + __libc_lock_lock (pd->exit_lock); + + int res= 0; + if (pd->tid > 0) + res = INTERNAL_SYSCALL_CALL (sched_getaffinity, pd->tid, + MIN (INT_MAX, cpusetsize), cpuset); + else + res = -EINVAL; + + __libc_lock_unlock (pd->exit_lock); + internal_signal_restore_set (&old_mask); + + if (res < 0) + return -res; /* Clean the rest of the memory the kernel didn't do. */ memset ((char *) cpuset + res, '\0', cpusetsize - res); diff --git a/sysdeps/pthread/Makefile b/sysdeps/pthread/Makefile index de146dddeb..0532b367de 100644 --- a/sysdeps/pthread/Makefile +++ b/sysdeps/pthread/Makefile @@ -217,6 +217,7 @@ tests += \ tst-pt-vfork1 \ tst-pt-vfork2 \ tst-pthread-exit-signal \ + tst-pthread-exited \ tst-pthread-mutexattr \ tst-pthread-mutexattr-2 \ tst-pthread-raise-blocked-self \ diff --git a/sysdeps/pthread/tst-pthread-exited.c b/sysdeps/pthread/tst-pthread-exited.c new file mode 100644 index 0000000000..8997752528 --- /dev/null +++ b/sysdeps/pthread/tst-pthread-exited.c @@ -0,0 +1,51 @@ +/* Test pthread interface which should return ESRCH when issues along + with a terminated pthread_t. + Copyright (C) 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 +#include +#include +#include +#include + +static void * +noop_thread (void *closure) +{ + return NULL; +} + +static int +do_test (void) +{ + pthread_t thr = xpthread_create (NULL, noop_thread, NULL); + + support_wait_for_thread_exit (); + + { + cpu_set_t cpuset; + int r = pthread_getaffinity_np (thr, sizeof (cpuset), &cpuset); + TEST_COMPARE (r, EINVAL); + } + + xpthread_join (thr); + + return 0; +} + +#include