Re: add-finalizer!
Martin Gasbichler <[email protected]> Wed, 28 Jun 2006 09:07:22 +0200
| Newsgroups | gmane.lisp.scheme.scsh |
|---|---|
| Message-ID | <[email protected]> |
"Emilio Lopes" <[email protected]> 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