[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Reasons, why Miss Scheme should collect her garbage before shutdown.

Dear developers of MzScheme, dear extension-programmers,

in an earlier message I wondered why no garbage collection is done
before MzScheme exits. No special reason was given.
Because of this ill-defined behaviour of MzScheme some otherwise easy
to program tasks can only be done with the help of dirty hacks as will
be shown below.

Something that works

- Often it is useful to bind the lifetime of an external object to a
lexical scope inside the Scheme-Environment, like so:

(let ((obj (make-external-object args)))
   (operation-on-external-object obj)

For example: 
- a buffer could be created which in the end must be written to a file
- some kind of communication could be started which in the end must be
terminated by special commands or 
- data-objects could be created in a foreign process that in the end
must be freed again.

Finalizers are both a very useful and versatile means to put a
controlled end to each object, because they are invoked before an
object is garbage-collected and you can use them to perform any action
on the object, like:
- write the buffer to a file
- close communications with special commands
- clear data out of a foreign process

Something that should work and why it fails

Consider the following example:

(define obj (make-external-object args))

Here, one might expect that the lifetime of the external object is
limited to that of the MzScheme-Process.
Noodles! This is not at all the case because no garbage-collection
ever happens before MzScheme is shutdown. So no finalizer will be
evoked and:
- the content of the buffer will vanish into nirvana and not at all be
written to any file
- the communication will not be ended correctly
- the foreign data will clutter the other processes namespace and

What could be done?

Best solution
MzScheme is changed so that she does collect her garbage before
Well ... no well-behaved woman would leave her house in a mess before
going on holiday, would she?

Second best solution
A proper exit-hook is provided that enables extension-programmers to
force a garbage-collection before shutdown.

Third best solution
In MzScheme-v200 there is a function scheme_add_atexit_closer() which
is designed to operate on custodian-registered objects and might be
used to emulate an exit-hook.

Clearly not a solution
scheme_exit is a pointer that can be set to a c-function which will be
called before MzScheme-shutdown. It is reserved for embedding programs
and if several extensions would set it - each one to its own
exit-procedure, of course - it would surely mess things up royally.

Why not go for the best and most clean solution?

Others did see the same problem

I searched the archives and discovered that - indeed - I'm not the
only person suffering from this ill-defined MzScheme-behaviour.

Following are some excerpts of a message that was sent to this
mail-list in 2000-08-08 by Mr. Fernout:

> I think the correct way to make an object with a protected resource
> (like a file handle) in MzScheme is to use both a finalizer and a
> custodian.
> My understanding, which may be incomplete or wrong, is:
> * When an object is garbage collected, a finalizer if any is called.
> * When Scheme shuts down, objects are not garbage collected.
> * Thus, you also need a custodian who will close the resource for 
> you.
> This approach seems like it would work, but is
> to me a little inelegant. Somehow I'd like to make just
> one call to MzScheme to protect a resource, rather
> than a couple which require defining a couple of functions.

Yes, messing with custodians only because there is no final
garbage-collection is not only 'inelegant' but painful and

One final plead

Here is my plead to those who are actively developing MzScheme: please
make MzScheme collect garbage before exit!

Sincerely yours and thank you for reading till the very end,