fix problems with custodian boxes, especially for a box whose custodian is shut down via an ancestor custodian

svn: r12680
This commit is contained in:
Matthew Flatt 2008-12-02 19:51:01 +00:00
parent 827bc8755b
commit c333fa8fb5
4 changed files with 47 additions and 2 deletions

View File

@ -116,6 +116,15 @@
((current-memory-use c) . >= . 100000))
c)))
(let ()
(define c1 (make-custodian (current-custodian)))
(define b1 (make-custodian-box c1 #t))
(define c2 (make-custodian c1))
(define b2 (make-custodian-box c2 #t))
(test '(#t #t) map custodian-box-value (list b1 b2))
(custodian-shutdown-all c1)
(test '(#f #f) map custodian-box-value (list b1 b2)))
;; ----------------------------------------
(report-errs)

View File

@ -264,10 +264,11 @@ inline static void mark_cust_boxes(NewGC *gc, Scheme_Custodian *cur)
SCHEME_CDR(prev) = next;
else
cur->cust_boxes = next;
--cur->num_cust_boxes;
}
pr = next;
}
cur->cust_boxes = NULL;
cur->checked_cust_boxes = cur->num_cust_boxes;
}
int BTC_thread_mark(void *p)

View File

@ -438,6 +438,7 @@ struct Scheme_Custodian {
#ifdef MZ_PRECISE_GC
int gc_owner_set;
Scheme_Object *cust_boxes;
int num_cust_boxes, checked_cust_boxes;
#endif
};

View File

@ -1467,12 +1467,27 @@ Scheme_Thread *scheme_do_close_managed(Scheme_Custodian *m, Scheme_Exit_Closer_F
}
}
#ifdef MZ_PRECISE_GC
{
Scheme_Object *pr = m->cust_boxes, *wb;
Scheme_Custodian_Box *cb;
while (pr) {
wb = SCHEME_CAR(pr);
cb = (Scheme_Custodian_Box *)SCHEME_BOX_VAL(wb);
if (cb) cb->v = NULL;
pr = SCHEME_CDR(pr);
}
m->cust_boxes = NULL;
}
#endif
m->count = 0;
m->alloc = 0;
m->boxes = NULL;
m->closers = NULL;
m->data = NULL;
m->mrefs = NULL;
m->shut_down = 1;
if (SAME_OBJ(m, start))
break;
@ -1715,10 +1730,29 @@ static Scheme_Object *make_custodian_box(int argc, Scheme_Object *argv[])
#ifdef MZ_PRECISE_GC
/* 3m */
{
Scheme_Object *wb, *pr;
Scheme_Object *wb, *pr, *prev;
wb = GC_malloc_weak_box(cb, NULL, 0);
pr = scheme_make_raw_pair(wb, cb->cust->cust_boxes);
cb->cust->cust_boxes = pr;
cb->cust->num_cust_boxes++;
/* The GC prunes the list of custodian boxes in accounting mode,
but prune here in case accounting is never triggered. */
if (cb->cust->num_cust_boxes > 2 * cb->cust->checked_cust_boxes) {
prev = pr;
pr = SCHEME_CDR(pr);
while (pr) {
wb = SCHEME_CAR(pr);
if (!SCHEME_BOX_VAL(pr)) {
SCHEME_CDR(prev) = SCHEME_CDR(pr);
--cb->cust->num_cust_boxes;
} else {
prev = pr;
}
pr = SCHEME_CDR(pr);
}
cb->cust->checked_cust_boxes = cb->cust->num_cust_boxes;
}
}
#else
/* CGC */