summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authordeischen <deischen@FreeBSD.org>2003-08-20 02:34:14 +0000
committerdeischen <deischen@FreeBSD.org>2003-08-20 02:34:14 +0000
commit9371b61282ed1e0de29164f2b0227baebfc1b12f (patch)
treec293ef23a30101995b652cd997dc7a6408f336eb /lib
parenta8da4c622c2839b220d4e96bf27320a291a19b68 (diff)
downloadFreeBSD-src-9371b61282ed1e0de29164f2b0227baebfc1b12f.zip
FreeBSD-src-9371b61282ed1e0de29164f2b0227baebfc1b12f.tar.gz
Add back a loop for up to PTHREAD_DESTRUCTOR_ITERATIONS to
destroy thread-specific data. Display a warning when thread specific data remains after PTHREAD_DESTRUCTOR_ITERATIONS. Reviewed by: davidxu
Diffstat (limited to 'lib')
-rw-r--r--lib/libkse/thread/thr_spec.c32
-rw-r--r--lib/libpthread/thread/thr_spec.c32
2 files changed, 40 insertions, 24 deletions
diff --git a/lib/libkse/thread/thr_spec.c b/lib/libkse/thread/thr_spec.c
index e2b6e2d..9491906 100644
--- a/lib/libkse/thread/thr_spec.c
+++ b/lib/libkse/thread/thr_spec.c
@@ -107,13 +107,18 @@ void
_thread_cleanupspecific(void)
{
struct pthread *curthread = _get_curthread();
+ void (*destructor)( void *);
void *data = NULL;
int key;
- void (*destructor)( void *);
+ int i;
- if (curthread->specific != NULL) {
- /* Lock the key table: */
- THR_LOCK_ACQUIRE(curthread, &_keytable_lock);
+ if (curthread->specific == NULL)
+ return;
+
+ /* Lock the key table: */
+ THR_LOCK_ACQUIRE(curthread, &_keytable_lock);
+ for (i = 0; (i < PTHREAD_DESTRUCTOR_ITERATIONS) &&
+ (curthread->specific_data_count > 0); i++) {
for (key = 0; (key < PTHREAD_KEYS_MAX) &&
(curthread->specific_data_count > 0); key++) {
destructor = NULL;
@@ -122,7 +127,8 @@ _thread_cleanupspecific(void)
(curthread->specific[key].data != NULL)) {
if (curthread->specific[key].seqno ==
key_table[key].seqno) {
- data = (void *)curthread->specific[key].data;
+ data = (void *)
+ curthread->specific[key].data;
destructor = key_table[key].destructor;
}
curthread->specific[key].data = NULL;
@@ -143,10 +149,14 @@ _thread_cleanupspecific(void)
THR_LOCK_ACQUIRE(curthread, &_keytable_lock);
}
}
- THR_LOCK_RELEASE(curthread, &_keytable_lock);
- free(curthread->specific);
- curthread->specific = NULL;
}
+ THR_LOCK_RELEASE(curthread, &_keytable_lock);
+ free(curthread->specific);
+ curthread->specific = NULL;
+ if (curthread->specific_data_count > 0)
+ stderr_debug("Thread %p has exited with leftover "
+ "thread-specific data after %d destructor iterations\n",
+ curthread, PTHREAD_DESTRUCTOR_ITERATIONS);
}
static inline struct pthread_specific_elem *
@@ -179,10 +189,8 @@ _pthread_setspecific(pthread_key_t key, const void *value)
if (pthread->specific[key].data == NULL) {
if (value != NULL)
pthread->specific_data_count++;
- } else {
- if (value == NULL)
- pthread->specific_data_count--;
- }
+ } else if (value == NULL)
+ pthread->specific_data_count--;
pthread->specific[key].data = value;
pthread->specific[key].seqno =
key_table[key].seqno;
diff --git a/lib/libpthread/thread/thr_spec.c b/lib/libpthread/thread/thr_spec.c
index e2b6e2d..9491906 100644
--- a/lib/libpthread/thread/thr_spec.c
+++ b/lib/libpthread/thread/thr_spec.c
@@ -107,13 +107,18 @@ void
_thread_cleanupspecific(void)
{
struct pthread *curthread = _get_curthread();
+ void (*destructor)( void *);
void *data = NULL;
int key;
- void (*destructor)( void *);
+ int i;
- if (curthread->specific != NULL) {
- /* Lock the key table: */
- THR_LOCK_ACQUIRE(curthread, &_keytable_lock);
+ if (curthread->specific == NULL)
+ return;
+
+ /* Lock the key table: */
+ THR_LOCK_ACQUIRE(curthread, &_keytable_lock);
+ for (i = 0; (i < PTHREAD_DESTRUCTOR_ITERATIONS) &&
+ (curthread->specific_data_count > 0); i++) {
for (key = 0; (key < PTHREAD_KEYS_MAX) &&
(curthread->specific_data_count > 0); key++) {
destructor = NULL;
@@ -122,7 +127,8 @@ _thread_cleanupspecific(void)
(curthread->specific[key].data != NULL)) {
if (curthread->specific[key].seqno ==
key_table[key].seqno) {
- data = (void *)curthread->specific[key].data;
+ data = (void *)
+ curthread->specific[key].data;
destructor = key_table[key].destructor;
}
curthread->specific[key].data = NULL;
@@ -143,10 +149,14 @@ _thread_cleanupspecific(void)
THR_LOCK_ACQUIRE(curthread, &_keytable_lock);
}
}
- THR_LOCK_RELEASE(curthread, &_keytable_lock);
- free(curthread->specific);
- curthread->specific = NULL;
}
+ THR_LOCK_RELEASE(curthread, &_keytable_lock);
+ free(curthread->specific);
+ curthread->specific = NULL;
+ if (curthread->specific_data_count > 0)
+ stderr_debug("Thread %p has exited with leftover "
+ "thread-specific data after %d destructor iterations\n",
+ curthread, PTHREAD_DESTRUCTOR_ITERATIONS);
}
static inline struct pthread_specific_elem *
@@ -179,10 +189,8 @@ _pthread_setspecific(pthread_key_t key, const void *value)
if (pthread->specific[key].data == NULL) {
if (value != NULL)
pthread->specific_data_count++;
- } else {
- if (value == NULL)
- pthread->specific_data_count--;
- }
+ } else if (value == NULL)
+ pthread->specific_data_count--;
pthread->specific[key].data = value;
pthread->specific[key].seqno =
key_table[key].seqno;
OpenPOWER on IntegriCloud