diff options
-rw-r--r-- | src/util/support/ChangeLog | 8 | ||||
-rw-r--r-- | src/util/support/threads.c | 54 |
2 files changed, 38 insertions, 24 deletions
diff --git a/src/util/support/ChangeLog b/src/util/support/ChangeLog index 4686f935b5..b0370a8df2 100644 --- a/src/util/support/ChangeLog +++ b/src/util/support/ChangeLog @@ -1,3 +1,11 @@ +2005-03-20 Alexandra Ellwood <lxs@mit.edu> + + * threads.c (thread_termination): Free array of pointers + to thread-specific data (t) on thread termination. Use + existing mutex to prevent the deletion of the array from + interfering with the global list of thread specific data + (used for library termination). + 2005-02-08 Ken Raeburn <raeburn@mit.edu> * threads.c (k5_key_delete) [pthread case]: Reset flags and diff --git a/src/util/support/threads.c b/src/util/support/threads.c index 51ad788143..e1e56e20da 100644 --- a/src/util/support/threads.c +++ b/src/util/support/threads.c @@ -117,30 +117,36 @@ static void thread_termination(void *); static void thread_termination (void *tptr) { - int i, pass, none_found; - struct tsd_block *t = tptr; - - /* Make multiple passes in case, for example, a libkrb5 cleanup - function wants to print out an error message, which causes - com_err to allocate a thread-specific buffer, after we just - freed up the old one. - - Shouldn't actually happen, if we're careful, but check just in - case. */ - - pass = 0; - none_found = 0; - while (pass < 4 && !none_found) { - none_found = 1; - for (i = 0; i < K5_KEY_MAX; i++) { - if (destructors_set[i] && destructors[i] && t->values[i]) { - void *v = t->values[i]; - t->values[i] = 0; - (*destructors[i])(v); - none_found = 0; - } - } - } + int err = k5_mutex_lock(&key_lock); + if (err == 0) { + int i, pass, none_found; + struct tsd_block *t = tptr; + + /* Make multiple passes in case, for example, a libkrb5 cleanup + function wants to print out an error message, which causes + com_err to allocate a thread-specific buffer, after we just + freed up the old one. + + Shouldn't actually happen, if we're careful, but check just in + case. */ + + pass = 0; + none_found = 0; + while (pass < 4 && !none_found) { + none_found = 1; + for (i = 0; i < K5_KEY_MAX; i++) { + if (destructors_set[i] && destructors[i] && t->values[i]) { + void *v = t->values[i]; + t->values[i] = 0; + (*destructors[i])(v); + none_found = 0; + } + } + } + free (t); + err = k5_mutex_unlock(&key_lock); + } + /* remove thread from global linked list */ } |