diff options
Diffstat (limited to 'sysdeps/generic/pt-destroy-specific.c')
-rw-r--r-- | sysdeps/generic/pt-destroy-specific.c | 57 |
1 files changed, 53 insertions, 4 deletions
diff --git a/sysdeps/generic/pt-destroy-specific.c b/sysdeps/generic/pt-destroy-specific.c index b627f87..642c61c 100644 --- a/sysdeps/generic/pt-destroy-specific.c +++ b/sysdeps/generic/pt-destroy-specific.c @@ -1,4 +1,4 @@ -/* __pthread_destory_specific. Generic version. +/* __pthread_destory_specific. Hurd version. Copyright (C) 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -18,11 +18,60 @@ Boston, MA 02111-1307, USA. */ #include <pthread.h> +#include <stdlib.h> + #include <pt-internal.h> void -__pthread_destory_specifc (struct __pthread *thread) +__pthread_destroy_specific (struct __pthread *thread) { - /* Not support, thus there cannot be any. */ - return; + int i; + int seen_one; + + /* Check if there is any thread specific data. */ + if (! thread->thread_specifics) + return; + + __pthread_key_lock_ready (); + + /* Iterate and call the destructors on any thread specific data. */ + for (;;) + { + seen_one = 0; + + __pthread_mutex_lock (&__pthread_key_lock); + + for (i = 0; i < __pthread_key_count && i < thread->thread_specifics_size; i ++) + { + void *value; + + if (__pthread_key_destructors[i] == PTHREAD_KEY_INVALID) + continue; + + value = thread->thread_specifics[i]; + if (value) + { + thread->thread_specifics[i] = 0; + + if (__pthread_key_destructors[i]) + { + seen_one = 1; + __pthread_key_destructors[i] (value); + } + } + } + + __pthread_mutex_unlock (&__pthread_key_lock); + + if (! seen_one) + break; + + /* This may take a very long time. Let those blocking on + pthread_key_create or pthread_key_delete make progress. */ + sched_yield (); + } + + free (thread->thread_specifics); + thread->thread_specifics = 0; + thread->thread_specifics_size = 0; } |