On Tue, Dec 16, 2008 at 7:36 PM, felix winkelmann <[email protected]> wrote:
> On Mon, Dec 15, 2008 at 11:57 PM, Alejandro Forero Cuervo
> <[email protected]> wrote:
>>
>> I have a question about finalizers.
>>
>> If you run the following in csi:
>>
>> (define x (list 1 2 3))
>> (begin (set-finalizer! x (lambda (o) (format #t "Delete: ~A~%" o))) #t)
>> (define y (list 4 5 6))
>> (begin (set-finalizer! y (let ((p x)) (lambda (o) (format #t "Delete: ~A:
>> ~A~%" o p)))) #t)
>> (gc #t)
>> (set! x #f)
>> (gc #t)
>>
>> Why do you get "Delete: (1 2 3)", the output of the finalizer for x,
>> even though the finalizer for y depends on the value of x?
>>
>> Am I misunderstanding the way finalizer procedures get executed?
>>
>
> A bug. The finalizer itself is not considered in the calculation whether
> something is still referenced or not (I think). I have to investigate.
>
Hi!
Please try attached patch. I have added it to trunk and the chicken-3
branch, and did some tests, but testing finalization is always somewhat
difficult.
cheers,
felix
Index: runtime.c
===================================================================
--- runtime.c (revision 12830)
+++ runtime.c (working copy)
@@ -2701,7 +2701,8 @@
/* Mark collectibles: */
for(msp = collectibles; msp < collectibles_top; ++msp)
if(*msp != NULL) mark(*msp);
-
+
+ /* mark GC roots: */
for(gcrp = gc_root_list; gcrp != NULL; gcrp = gcrp->next)
mark(&gcrp->value);
@@ -2779,6 +2780,9 @@
else {
j = fcount = 0;
+ for(flist = finalizer_list; flist != NULL; flist = flist->next)
+ mark(&flist->finalizer);
+
for(flist = finalizer_list; flist != NULL; flist = flist->next) {
if(j < C_max_pending_finalizers) {
if(!is_fptr(C_block_header(flist->item)))
@@ -2786,7 +2790,6 @@
}
mark(&flist->item);
- mark(&flist->finalizer);
}
}
_______________________________________________
Chicken-users mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/chicken-users