testinterpreterplugin and primitive cleaning?

Andreas Raab andreas.raab at gmx.de
Sat May 17 00:43:29 UTC 2003


Hi,

> Inside a primitive's C code I have code that uses a library call which
> allocates memory and returns it to the caller.  I convert 
> that to an oop, to be stored in an object.  How do I call
> the library cleanup code when the object is destroyed
> (GCed if you prefer)?

Here's an example:

Object subclass: #MyClass
	instanceVariableNames: 'handle'
	classVariableNames: 'MyClassRegistry'
	poolDictionaries: ''
	category: 'My Project'

With 'handle' representing the resource (memory) and 'MyClassRegistry' being
a class variable containing special kind of registry (see below). The
relevant methods for handling the cleanup are:

MyClass>>executor
	"Answer an object that knows what to do when I get destroyed. What
follows below is the exact implementation found in class Object but shown
here to emphasize that one can answer any object knowing what to do in this
case. But since most objects know what needs to be done for this handing us
a copy is just fine"
	^self shallowCopy actAsExecutor

MyClass>>actAsExecutor
	"I am being used as an executor. This typically means I don't need
any state besides the one that's associated with the resource I should be
closing. In order to preserve space I may do some cleanup."
	^super actAsExecutor "yes, this method *is* implemented in Object

MyClass>>finalize
	"Finalize the resource associated with the receiver. This message is
only sent during the finalization process. There is NO garantuee that the
resource associated with the receiver hasn't been free'd before so take care
that you don't run into trouble - this all may happen with interrupt
priority."
	self closeHandleWithNoErrorReportingWhatsoever.

With (a combination of) the above three methods you have set up everything
you need for MyClass. Minimally, only #finalize is required but often you
may want to implement one of the other two.

Now, all you need to do a bit of management, e.g.,

MyClass class>>initialize
	"MyClass initialize"
	MyClassRegistry ifNil:[MyClassRegistry := WeakRegistry new].

WeakRegistry manages a lot of the complexity behind the scenes, so once you
got it you can simply do something like:

MyClass>>register
	"register me once I have a handle assigned"
	MyClassRegistry add: self.

And once the instance of MyClass gets GCed everything else follows
automatically. In addition, if you free the object someplace else, you may
add something like:

MyClass>>unregister
	"unregister me once my handle was released"
	MyClassRegistry remove: self.

That's about all that is to it. If you need some examples, check out
StandardFileStream, MPEGFile, or Socket all of which use the same scheme.

As an extra note: Sometimes you may not want to have finalization to happen
'randomly' but only at specific points in time (for example, in 3D all
finalization for objects used during rendering must only happen once the
frame is complete). It is possible to do this but it requires a bit more
manual work.

Cheers,
  - Andreas



More information about the Squeak-dev mailing list