pthread_key
authorGNU Libc Maintainers <debian-glibc@lists.debian.org>
Sun, 10 Jul 2022 20:29:34 +0000 (21:29 +0100)
committerAurelien Jarno <aurel32@debian.org>
Sun, 10 Jul 2022 20:29:34 +0000 (21:29 +0100)
commit 315c9e794a5fb8f9672081dbd7493b5fd036ab05
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Mon Feb 14 00:15:13 2022 +0100

    htl: Make pthread_[gs]etspecific not check for key validity

    Since __pthread_key_create might be concurrently reallocating the
    __pthread_key_destructors array, it's not safe to access it without the
    mutex held. Posix explicitly says we are allowed to prefer performance
    over error detection.

commit 33038a7d917889547c711be158ed34739af26351
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Mon Feb 14 00:47:18 2022 +0100

    mach: Fix LLL_SHARED value

    Mach defines GSYNC_SHARED, not SYNC_SHARED.

commit 06dbfcced3101886029ea3a46bcc98887d60f61e
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Mon Feb 14 01:38:03 2022 +0100

    htl: Fix initializing the key lock

    The static pthread_once_t in the pt-key.h header was creating one
    pthread_once_t per includer.  We have to use a shared common
    pthread_once_t instead.

commit 7a06be051c01b4325927efab5b4e4280bb4a5a42
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Mon Feb 14 01:39:35 2022 +0100

    htl: Destroy thread-specific data before releasing joins

    Applications may want to assume that after pthread_join() returns, all
    thread-specific data has been released.

Gbp-Pq: Topic hurd-i386
Gbp-Pq: Name pthread_key.diff

htl/pt-exit.c
mach/lowlevellock.h
sysdeps/htl/pt-getspecific.c
sysdeps/htl/pt-key-create.c
sysdeps/htl/pt-key.h
sysdeps/htl/pt-setspecific.c

index 9f633369d39a7cf356f1188592d8c5012dc87c0f..8e9552923f18fba6a48201916d9cbf0be104e9b1 100644 (file)
@@ -54,6 +54,9 @@ __pthread_exit (void *status)
     /* We are the last thread.  */
     exit (0);
 
+  /* Destroy any thread specific data.  */
+  __pthread_destroy_specific (self);
+
   /* Note that after this point the process can be terminated at any
      point if another thread calls `pthread_exit' and happens to be
      the last thread.  */
@@ -92,9 +95,6 @@ __pthread_exit (void *status)
       break;
     }
 
-  /* Destroy any thread specific data.  */
-  __pthread_destroy_specific (self);
-
   /* Destroy any signal state.  */
   __pthread_sigstate_destroy (self);
 
index e2344ab431a238b37ad193d6e4bc6f427a9aaa08..bf94b4d9852af4420c02886e330a78e88e382f44 100644 (file)
@@ -35,7 +35,7 @@
 #define LLL_LOCK_INITIALIZER   0
 
 #define LLL_PRIVATE        0
-#define LLL_SHARED         SYNC_SHARED
+#define LLL_SHARED         GSYNC_SHARED
 
 /* Interruptible version of __gsync_wait.  */
 extern kern_return_t __gsync_wait_intr
index 374dbfee73964d9bb34f2b2a7f9ef9e713c41117..3d437359e1f62eba6cf82176aeb45c2d6970eada 100644 (file)
@@ -25,8 +25,7 @@ __pthread_getspecific (pthread_key_t key)
 {
   struct __pthread *self;
 
-  if (key < 0 || key >= __pthread_key_count
-      || __pthread_key_destructors[key] == PTHREAD_KEY_INVALID)
+  if (key < 0 || key >= __pthread_key_count)
     return NULL;
 
   self = _pthread_self ();
index 1219eb9e1c574f83fc4f11e2a390dc93799bcd12..a5f8cf93186bf07cb4ab133fdebc9e4fac3300e7 100644 (file)
@@ -24,6 +24,7 @@
 #include <pthreadP.h>
 
 pthread_mutex_t __pthread_key_lock;
+pthread_once_t __pthread_key_once = PTHREAD_ONCE_INIT;
 
 void (**__pthread_key_destructors) (void *arg);
 int __pthread_key_size;
index ba1b40dbb267791a85fab3545b7ea47f60e04786..d5e8312b259ae0b2c1e5447ac6c4c3b1ce549ae0 100644 (file)
@@ -47,14 +47,15 @@ extern int __pthread_key_invalid_count;
 /* Protects the above variables.  This must be a recursive lock: the
    destructors may call pthread_key_delete.  */
 extern pthread_mutex_t __pthread_key_lock;
+
+/* Protects the initialization of the mutex above.  */
+extern pthread_once_t __pthread_key_once;
 \f
 #include <assert.h>
 
 static inline void
 __pthread_key_lock_ready (void)
 {
-  static pthread_once_t o = PTHREAD_ONCE_INIT;
-
   void do_init (void)
   {
     int err;
@@ -73,5 +74,5 @@ __pthread_key_lock_ready (void)
     assert_perror (err);
   }
 
-  __pthread_once (&o, do_init);
+  __pthread_once (&__pthread_key_once, do_init);
 }
index 471060d1cb5c05f1c9e3529080c4a88b1cd0c5b3..380e7a23e6ebb67a13f458c46ae1f6ab9138d85e 100644 (file)
@@ -25,8 +25,7 @@ __pthread_setspecific (pthread_key_t key, const void *value)
 {
   struct __pthread *self = _pthread_self ();
 
-  if (key < 0 || key >= __pthread_key_count
-      || __pthread_key_destructors[key] == PTHREAD_KEY_INVALID)
+  if (key < 0 || key >= __pthread_key_count)
     return EINVAL;
 
   if (key >= self->thread_specifics_size)