[07/15] nptl: Use exit_lock when accessing TID on pthread_setaffinity

Message ID 20210930200051.1017457-8-adhemerval.zanella@linaro.org
State Superseded
Headers
Series Fix various NPTL synchronization issues |

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent

Commit Message

Adhemerval Zanella Sept. 30, 2021, 8 p.m. UTC
  Also return ESRCH if the thread is already terminated at the time of
the call.  This is slight better than setting the calling thread
affinity (current behaviour).

Checked on x86_64-linux-gnu.
---
 nptl/pthread_setaffinity.c           | 25 +++++++++++++++----------
 sysdeps/pthread/tst-pthread-exited.c |  7 +++++++
 2 files changed, 22 insertions(+), 10 deletions(-)
  

Patch

diff --git a/nptl/pthread_setaffinity.c b/nptl/pthread_setaffinity.c
index 2ae6ae694c..cefc48e7c5 100644
--- a/nptl/pthread_setaffinity.c
+++ b/nptl/pthread_setaffinity.c
@@ -15,10 +15,8 @@ 
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <errno.h>
+#include <libc-lock.h>
 #include <pthreadP.h>
-#include <sysdep.h>
-#include <sys/types.h>
 #include <shlib-compat.h>
 
 
@@ -26,15 +24,22 @@  int
 __pthread_setaffinity_new (pthread_t th, size_t cpusetsize,
 			   const cpu_set_t *cpuset)
 {
-  const struct pthread *pd = (const struct pthread *) th;
-  int res;
+  struct pthread *pd = (struct pthread *) th;
 
-  res = INTERNAL_SYSCALL_CALL (sched_setaffinity, pd->tid, cpusetsize,
-			       cpuset);
+  /* Block all signals, as required by pd->exit_lock.  */
+  sigset_t old_mask;
+  __libc_signal_block_all (&old_mask);
+  __libc_lock_lock (pd->exit_lock);
 
-  return (INTERNAL_SYSCALL_ERROR_P (res)
-	  ? INTERNAL_SYSCALL_ERRNO (res)
-	  : 0);
+  int res = pd->tid == 0
+	    ? ESRCH
+	    : -INTERNAL_SYSCALL_CALL (sched_setaffinity, pd->tid, cpusetsize,
+				      cpuset);
+
+  __libc_lock_unlock (pd->exit_lock);
+  __libc_signal_restore_set (&old_mask);
+
+  return res;
 }
 versioned_symbol (libc, __pthread_setaffinity_new,
 		  pthread_setaffinity_np, GLIBC_2_34);
diff --git a/sysdeps/pthread/tst-pthread-exited.c b/sysdeps/pthread/tst-pthread-exited.c
index c27e856dea..567d6b9b49 100644
--- a/sysdeps/pthread/tst-pthread-exited.c
+++ b/sysdeps/pthread/tst-pthread-exited.c
@@ -43,6 +43,13 @@  do_test (void)
     TEST_COMPARE (r, ESRCH);
   }
 
+  {
+    cpu_set_t cpuset;
+    CPU_ZERO (&cpuset);
+    int r = pthread_setaffinity_np (thr, sizeof (cpuset), &cpuset);
+    TEST_COMPARE (r, ESRCH);
+  }
+
   xpthread_join (thr);
 
   return 0;