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
/* 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. */
break;
}
- /* Destroy any thread specific data. */
- __pthread_destroy_specific (self);
-
/* Destroy any signal state. */
__pthread_sigstate_destroy (self);
#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
{
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 ();
#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;
/* 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;
assert_perror (err);
}
- __pthread_once (&o, do_init);
+ __pthread_once (&__pthread_key_once, do_init);
}
{
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)