From ca57adcf2db458276b778b18061de1e5ccecde23 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 22 Jun 2015 16:43:42 +0800 Subject: [PATCH] fix slow leak in link-establishing `thread-resume` Using `(thread-resume t1 t2)` would not prevent a GC of t1, but it would create an intermediate record to make the link from t1 to t2, and that intermediate record would leak due to a missing level of indirection in a table-cleanup traveral. The leak not only accumulated memory, it also caused ever slower traversals of the table in an attempt to clean up. (Since the leak is small and the leaking object is not directly accessible, I don't have a good idea on how to test this repair automatically, but see the program in the PR.) Closes PR 15099. --- racket/src/racket/src/thread.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index ae282e69c8..8687a04365 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -5779,15 +5779,17 @@ static void add_transitive_resume(Scheme_Thread *promote_to, Scheme_Thread *p) promote_to->transitive_resumes = (Scheme_Object *)ht; } else { /* Purge ht entries for threads that are now dead: */ - Scheme_Hash_Table *gone= NULL; + Scheme_Hash_Table *gone = NULL; + Scheme_Object *b; int i; ht = (Scheme_Hash_Table *)promote_to->transitive_resumes; for (i = ht->size; i--; ) { if (ht->vals[i]) { - if (!SCHEME_PTR_VAL(ht->keys[i]) - || (SAME_TYPE(SCHEME_TYPE(ht->keys[i]), scheme_weak_box_type) - && !SCHEME_WEAK_BOX_VAL(ht->vals[i]))) { + b = SCHEME_PTR_VAL(ht->keys[i]); + if (!b + || (SAME_TYPE(SCHEME_TYPE(b), scheme_weak_box_type) + && !SCHEME_WEAK_BOX_VAL(b))) { /* This one is dead */ if (!gone) gone = scheme_make_hash_table(SCHEME_hash_ptr);