Next: syslib structs safe data, Previous: syslib structs safe printer, Up: syslib structs safe [Index]
Vicare allows structs to be finalised either explicitly or automatically by the garbage collector, by applying a destructor function to them; here is how automatic finalisation works:
vicare> (define-struct duo (one two)) vicare> (set-struct-type-destructor! (struct-type-descriptor duo) (lambda (stru) (printf "destroying ~s\n" stru))) vicare> (make-duo 1 2) $1 = (struct duo (one 1) (two 2)) vicare> (collect) destroying #[struct duo one=1 two=2] vicare>
A destructor function is associated to a struct–type by registering it in the struct–type descriptor. After a destructor is set in the descriptor: new instances of the struct–type are registered, upon creation, into an internal guardian, iklib guardians for details; whenever such structs are garbage collected: the guardian applies the destructor to them.
When the destructor is called by the garbage collector: exceptions
raised by it are catched with guard
and discarded; destructor
functions should take care of exceptions by themselves.
It is possible for a destructor function to be applied multiple times to the same struct: once a destructor is set in the descriptor, it can be explicitly applied to structs and later applied again by the garbage collector. Destructor functions must be written in such a way that multiple applications are not a problem. For example, it is usually possible, upon destruction, to reset some struct fields to the void object: when the destructor detects a field set to void, it knows that the struct has already been finalised.
Select the procedure destructor as destructor for data structs of
type std; return the old destructor function or #f
if no
destructor was set for std. The destructor accepts a single
argument being the struct instance to finalise; the destructor can
return unspecified values.
Return #f
or a procedure being the destructor for instances of
std.
Select data structs destruction logging mode for debugging purposes. When a struct is finalised by the garbage collector, using the destructor registered in the RTD:
#f
: no additional actions are
performed.
#t
: the function
struct-guardian-log
is used to log the operations to the textual
output port returned by current-error-port
.
See the documentation of struct-guardian-log
for the calling
protocol of the logger functions.
Built in logger function to be used to log struct finalisation
operations by the garbage collector. struct is the instance to be
finalised; exception is #f
or an object raised by the struct
destructor; action is one of the symbols:
before-destruction
, after-destruction
, exception
.
When this function is used as value for the parameter
struct-guardian-logger
:
registration
and
exception set to #f
.
before-destruction
and
exception set to #f
.
after-destruction
and
exception set to #f
.
exception
and exception set to the raised object.
The current implementation is the following:
(define (struct-guardian-log S E action) (case action ((registration) (fprintf (current-error-port) "*** Vicare debug: struct guardian: registered struct:\n\ ***\t~s\n" S)) ((before-destruction) (fprintf (current-error-port) "*** Vicare debug: struct guardian: before destruction:\n\ ***\t~s\n" S)) ((after-destruction) (fprintf (current-error-port) "*** Vicare debug: struct guardian: after destruction:\n\ ***\t~s\n" S)) ((exception) (fprintf (current-error-port) "*** Vicare debug: struct guardian: exception:\n\ ***\t~s\n\ ***\t~s\n" S E)) (else (assertion-violation 'struct-guardian-log "invalid action in struct destruction process" S action))))
Next: syslib structs safe data, Previous: syslib structs safe printer, Up: syslib structs safe [Index]