Subject: [clisp-list] howto: Finalization in CLISP

From: "Hoehle, Joerg-Cyril" <[email-masked]>
Date: Wed Jul 10 04:01:05 2002

Hi,

>> FINALIZE in CLISP does not guarantee finalization. Although it is
>> invoked by the garbage collector, it is not used when CLISP exists.

This was a design choice when finalizers where introduced. I feel it's acceptable for UNIX, less so for other OS.

>this is easy to fix - just run all finalizers on exit.  should it be?
>what are the issues?  (obviously, the possible errors while running
>the finalizers have to be ignored -- what else?)

o Debate whether it is acceptable that programmer definable Lisp code is still run after EXT:EXIT has been called.

o Finalizers which do nothing more than free() or close[socket]() are superfluous and waste precious time when an application has been ordered to exit. I.e. all finalizers for resources which the OS closes itself upon program exit.

However, some resources are not freed when an application exits. E.g. shared memory, which is used a lot in AmigaOS, and I've been told that MS-Windows also has different types of memory (and B and C pointers?).

o To obtain finalizers, GC must be run. To obtain all of them, a full GC across all generations must be run. I doubt this is accepted by users after they said EXT:exit, *especially* if only free() is to be called (what the OS does by itself).

o Ordering of finalizers may be an issue. One would wish for e.g. sockets to be released before the winsock library is released as well.
To a first approximation, it looks like finalizers and GC must be run iteratively, until a stable point is reached, so the reference to winsock hold by the reference to a socket will be cut by the first GC+finalization sweep which closes the socket and be ready to be released in the second iteration.
This sounds quite more work than benefit, doesn't it?

o You mention errors whithin finalizer scope. This is a topic which must be documented independently of program exit behaviour.
CLISP must document that finalizers are removed from the lisp before their code is invoked. Thus, if an error occurs, the finalizer will not be called a second time. Or if it's just the opposite behaviour, document that (I didn't look).

Note that it may not be acceptable for programmers and users that finalizers, which are invoked quasi asynchronously to program execution (from a high level POV), may cause CLISP to signal error at any time within their code.
This issue may have to be changed as well.
o put ignore-errors around each call to a finalizer, or
o put a single ignore-errors around the complete finalization (thus if an error occurs, remaining finalizers are not called, but they ought to be after the next GC).

Regards,
	Jorg Hohle.

---

From: Sam Steingold <[email-masked]>
Date: Wed Jul 10 07:43:06 2002

> * In message <[email-masked]>
> * On the subject of "[clisp-list] howto: Finalization in CLISP"
> * Sent on Wed, 10 Jul 2002 13:00:11 +0200
> * Honorable "Hoehle, Joerg-Cyril" <[email-masked]> writes:
>
> This was a design choice when finalizers where introduced. I feel it's
> acceptable for UNIX, less so for other OS.
>
> o Debate whether it is acceptable that programmer definable Lisp code
> is still run after EXT:EXIT has been called.

finalizers are "die hooks", so this is okay.

> o Finalizers which do nothing more than free() or close[socket]() are
> superfluous and waste precious time when an application has been
> ordered to exit. I.e. all finalizers for resources which the OS closes
> itself upon program exit.

sockets and files are already closed on exit.

> However, some resources are not freed when an application
> exits. E.g. shared memory, which is used a lot in AmigaOS, and I've
> been told that MS-Windows also has different types of memory (and B
> and C pointers?).

this should not be done using finalizers - after all they are hooks
into GC.

> o To obtain finalizers, GC must be run. To obtain all of them, a full
> GC across all generations must be run. I doubt this is accepted by
> users after they said EXT:exit, *especially* if only free() is to be
> called (what the OS does by itself).

nope.  just go over O(all_finalizers).

> o Ordering of finalizers may be an issue. One would wish for
> e.g. sockets to be released before the winsock library is released as
> well.

neither has anything to do with finalizers.
both are already being done.

> To a first approximation, it looks like finalizers and GC must be run
> iteratively, until a stable point is reached, so the reference to
> winsock hold by the reference to a socket will be cut by the first
> GC+finalization sweep which closes the socket and be ready to be
> released in the second iteration.

irrelevant, see above.

> o You mention errors whithin finalizer scope. This is a topic which
> must be documented independently of program exit behaviour.
> CLISP must document that finalizers are removed from the lisp before
> their code is invoked. Thus, if an error occurs, the finalizer will
> not be called a second time. Or if it's just the opposite behaviour,
> document that (I didn't look).

errors are handled normally - via the error reploop

> Note that it may not be acceptable for programmers and users that
> finalizers, which are invoked quasi asynchronously to program
> execution (from a high level POV), may cause CLISP to signal error at
> any time within their code.

lisp gives you ample opportunity to shoot yourself in the foot.

> o put a single ignore-errors around the complete finalization (thus if
> an error occurs, remaining finalizers are not called, but they ought
> to be after the next GC).

I guess the *DRIVER* will have to be bound to NIL (or something) around
the finalization in quit().

BTW, why wasn't module-finalization not implemented?

--
Sam Steingold (http://www.podval.org/~sds) running RedHat7.2 GNU/Linux
<http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/>
<http://www.mideasttruth.com/> <http://www.palestine-central.com/links.html>
The world is coming to an end.  Please log off.