scsh-users
[Top] [All Lists]

Re: add-finalizer!

To: "Emilio Lopes" <eclig@gmx.net>
Subject: Re: add-finalizer!
From: Martin Gasbichler <gasbichl@informatik.uni-tuebingen.de>
Date: Wed, 28 Jun 2006 09:07:22 +0200
Cc: scsh-users@scsh.net
List-id: <scsh-users.list-id.scsh.net>
"Emilio Lopes" <eclig@gmx.net> writes:

> I have here some objects whose creation involves starting external
> processes.  I would like these processes to be properly shut down when
> the corresponding objects are garbage-collected.
>
> So I tried using `add-finalizer!' for this purpose and couldn't get it
> to work.  Here is an example:
>
>    Welcome to scsh 0.6.7 (RC 1)
>    Type ,? for help.
>    > ,open define-record-types primitives
>    > (define-record-type foo :foo
>        (really-make-foo x)
>        (x foo:x))
>    > (define bar #f)
>    > (define (make-foo x)
>        (let ((new-foo (really-make-foo x)))
>          (add-finalizer! new-foo
>                          (lambda (obj)
>                            (set! bar 1)))
>          new-foo))
>    > (make-foo 43)
>    '#{Foo}
>    > ,collect
>    Before: 10608482 words free in semispace
>    After:  10673414 words free in semispace
>    > bar
>    #f
>    >
>
> I was expecting `bar' to be 1 at this point.  The same example works
> as expected under Scheme 48 1.3.
>
> Isn't this the way it's supposed to work?

The problem is that NEW-FOO is part of the closure that you pass as
the finializer and thus can never be GCed (since the finalizer closure
is always alive, NEW-FOO is always alive).

You therefore need to re-write your code as follows:

Welcome to scsh 0.6.7 (R6RS)
Type ,? for help.
>  ,open define-record-types primitives
> (define-record-type foo :foo
       (really-make-foo x)
       (x foo:x))
> (define bar #f)
> (define (finalize-foo! a-foo) (set! bar 1))
> (define (make-foo x)  
    (let ((new-foo (really-make-foo x)))
      (add-finalizer! new-foo finalize-foo!)
      new-foo))
> (make-foo 43)
'#{Foo}
> ,collect
Before: 1204331 words free in semispace
After:  1294606 words free in semispace
>  bar
#f                    [1]
>  ,collect
Before: 1287285 words free in semispace
After:  1295642 words free in semispace
>  bar
1


Your code works as expected in S48 1.3 because S48 1.3 uses a
different environment representation where only needed variables are
contained in a closure's environment.


Footnotes: 
[1]  the finalizer did not run here because the focus object (##) is bound to 
{Foo}


-- 
Martin

<Prev in Thread] Current Thread [Next in Thread>