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:
parent
827bc8755b
commit
c333fa8fb5
|
@ -116,6 +116,15 @@
|
||||||
((current-memory-use c) . >= . 100000))
|
((current-memory-use c) . >= . 100000))
|
||||||
c)))
|
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)
|
(report-errs)
|
||||||
|
|
|
@ -264,10 +264,11 @@ inline static void mark_cust_boxes(NewGC *gc, Scheme_Custodian *cur)
|
||||||
SCHEME_CDR(prev) = next;
|
SCHEME_CDR(prev) = next;
|
||||||
else
|
else
|
||||||
cur->cust_boxes = next;
|
cur->cust_boxes = next;
|
||||||
|
--cur->num_cust_boxes;
|
||||||
}
|
}
|
||||||
pr = next;
|
pr = next;
|
||||||
}
|
}
|
||||||
cur->cust_boxes = NULL;
|
cur->checked_cust_boxes = cur->num_cust_boxes;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BTC_thread_mark(void *p)
|
int BTC_thread_mark(void *p)
|
||||||
|
|
|
@ -438,6 +438,7 @@ struct Scheme_Custodian {
|
||||||
#ifdef MZ_PRECISE_GC
|
#ifdef MZ_PRECISE_GC
|
||||||
int gc_owner_set;
|
int gc_owner_set;
|
||||||
Scheme_Object *cust_boxes;
|
Scheme_Object *cust_boxes;
|
||||||
|
int num_cust_boxes, checked_cust_boxes;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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->count = 0;
|
||||||
m->alloc = 0;
|
m->alloc = 0;
|
||||||
m->boxes = NULL;
|
m->boxes = NULL;
|
||||||
m->closers = NULL;
|
m->closers = NULL;
|
||||||
m->data = NULL;
|
m->data = NULL;
|
||||||
m->mrefs = NULL;
|
m->mrefs = NULL;
|
||||||
|
m->shut_down = 1;
|
||||||
|
|
||||||
if (SAME_OBJ(m, start))
|
if (SAME_OBJ(m, start))
|
||||||
break;
|
break;
|
||||||
|
@ -1715,10 +1730,29 @@ static Scheme_Object *make_custodian_box(int argc, Scheme_Object *argv[])
|
||||||
#ifdef MZ_PRECISE_GC
|
#ifdef MZ_PRECISE_GC
|
||||||
/* 3m */
|
/* 3m */
|
||||||
{
|
{
|
||||||
Scheme_Object *wb, *pr;
|
Scheme_Object *wb, *pr, *prev;
|
||||||
wb = GC_malloc_weak_box(cb, NULL, 0);
|
wb = GC_malloc_weak_box(cb, NULL, 0);
|
||||||
pr = scheme_make_raw_pair(wb, cb->cust->cust_boxes);
|
pr = scheme_make_raw_pair(wb, cb->cust->cust_boxes);
|
||||||
cb->cust->cust_boxes = pr;
|
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
|
#else
|
||||||
/* CGC */
|
/* CGC */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user