summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/util/support/ChangeLog8
-rw-r--r--src/util/support/threads.c54
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 */
}