summaryrefslogtreecommitdiff
path: root/libpthread/linuxthreads/specific.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-03-12 20:56:59 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-03-12 20:56:59 +0000
commit52c9ef85a65f4dc25a4d1ff79c0fba1ed53ef43a (patch)
tree4b034bbe45a4e21907dda9e0a2af6d9adc2b63d0 /libpthread/linuxthreads/specific.c
parenta8e76cbe147263a58d9e70e426d295858f9cd308 (diff)
linuxthreads fixes from Will Newton (will.newton AT gmail.com):
* share Sys V semaphores in order to get appropriate SEM_UNDO semantics. * correct guardaddr in pthread_free() for TLS case * move spinlock unlocking before restart() * When exit was called from a signal handler, the restart from the manager processing the exit request instead restarted the thread in pthread_cond_timedwait. (see http://sources.redhat.com/ml/libc-ports/2006-05/msg00000.html)
Diffstat (limited to 'libpthread/linuxthreads/specific.c')
-rw-r--r--libpthread/linuxthreads/specific.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/libpthread/linuxthreads/specific.c b/libpthread/linuxthreads/specific.c
index 92eec3d99..764bf1e95 100644
--- a/libpthread/linuxthreads/specific.c
+++ b/libpthread/linuxthreads/specific.c
@@ -104,13 +104,14 @@ int pthread_key_delete(pthread_key_t key)
that if the key is reallocated later by pthread_key_create, its
associated values will be NULL in all threads.
- If no threads have been created yet, clear it just in the
- current thread. */
+ If no threads have been created yet, or if we are exiting, clear
+ it just in the current thread. */
struct pthread_key_delete_helper_args args;
args.idx1st = key / PTHREAD_KEY_2NDLEVEL_SIZE;
args.idx2nd = key % PTHREAD_KEY_2NDLEVEL_SIZE;
- if (__pthread_manager_request != -1)
+ if (__pthread_manager_request != -1
+ && !(__builtin_expect (__pthread_exit_requested, 0)))
{
struct pthread_request request;
@@ -203,8 +204,9 @@ void __pthread_destroy_specifics()
__pthread_lock(THREAD_GETMEM(self, p_lock), self);
for (i = 0; i < PTHREAD_KEY_1STLEVEL_SIZE; i++) {
if (THREAD_GETMEM_NC(self, p_specific[i]) != NULL) {
- free(THREAD_GETMEM_NC(self, p_specific[i]));
+ void *p = THREAD_GETMEM_NC(self, p_specific[i]);
THREAD_SETMEM_NC(self, p_specific[i], NULL);
+ free(p);
}
}
__pthread_unlock(THREAD_GETMEM(self, p_lock));