scsh-users
[Top] [All Lists]

Re: Process forms in finalizers

To: "Emilio Lopes" <eclig@gmx.net>
Subject: Re: Process forms in finalizers
From: Martin Gasbichler <gasbichl@informatik.uni-tuebingen.de>
Date: Fri, 30 Jun 2006 08:59:37 +0200
Cc: scsh-users@scsh.net
List-id: <scsh-users.list-id.scsh.net>
"Emilio Lopes" <eclig@gmx.net> writes:

> I encountered an interesting problem when trying to run an external
> process from a finalizer.  I'm writing this message mostly for
> documenting my experience for others that might try to achieve the
> same.
>
> My first try was the obvious (see my previous e-mail for the whole
> example):
>
>    (define (finalize-foo! a-foo)
>      (& (touch "/tmp/huhu")
>         (> 1 "/dev/null")
>         (= 2 1)))
>
> This causes Scsh to crash when GCing:
>
>    > ,collect
>    Before: 10545979 words free in semispace
>    After:  10645034 words free in semispace
>    > 155 / 1548 <- 1580 <- 3864 <- 3871 <- 3880 <- 3915 <- 1607 <-
> 1108 <- 1604 <- 1108 <- 1314 <- 1284 <- 1108 <-
>    Process scheme exited abnormally with code 123
>
> (BTW, what is the meaning of the funny numbers above?)

The list of numbers is a backtrace of the crash. You can lookup the
corresponding procedure names in build/initial.debug.

> After somme twiddling I finally came to something that works:
>
>    (define (finalize-foo! a-foo)
>      (call-with-output-file  "/dev/null"
>        (lambda (null-port)
>          (fork (lambda ()
>                  (dup null-port 1)
>                  (dup null-port 2)
>                  (exec "/usr/bin/touch" "/tmp/huhu"))
>                #t))))
>
> The crucial factor here is the second argument to `fork', #t.  The manual 
> says:
>
>    The optional boolean argument continue-threads? specifies whether the
>    currently active threads continue to run in the child or not. The
>    default is #f.
>
> I guess this has something to do with the collector running in its own
> thread, but I can't really explain the problem.

Yes, the finalizers are running in their own thread and presumably
only that thread continued to run in the forked thread. In general,
you should not do anything "complicated" in a finalizer because there
is not much protection for the execution of a finalizer. It's often
much better to write information about the dead objects into a queue
and process this queue in a separate thread.

-- 
Martin

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