testinterpreterplugin and primitive cleaning?

Ragnar Hojland Espinosa ragnar at linalco.com
Mon May 19 18:00:32 UTC 2003


On Fri, May 16, 2003 at 07:02:05PM -0700, Ned Konz wrote:
> On Friday 16 May 2003 05:24 pm, Ragnar Hojland Espinosa wrote:
> > 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)?
> 
> So the library allocates the memory outside of Squeak? How do you 
> safely convert that to an oop?

Half of the time I dont know what I'm doing, the other half I don't know
what to do :)  This is what I've currently been able to figure out:


primLDAPConnectTo: aHost port: aPort
<primitive: 'primitiveLDAPConnectTo' module: 'LDAPPlugin'>
self primitiveFailed

ldapRecordSize
	^ self cCode: 'sizeof(LDAPPluginT)' inSmalltalk: [self error:'boinggg']

ldapResultValueOf: oop
	self returnTypeC: 'LDAPPluginResultT *'.
	interpreterProxy success:
		((interpreterProxy isIntegerObject: oop) not and:
		[(interpreterProxy isBytes: oop) and:		
		[(interpreterProxy slotSizeOf: oop) = (self cCode: 'sizeof(LDAPPluginResultT)')]]).
	interpreterProxy failed 
		ifTrue: [ ^ nil ] 
		ifFalse: [ | i |
			i _ self cCoerce: (interpreterProxy firstIndexableField: oop) to: 'int'.
		     	^ self cCode: '(LDAPPluginResultT*) i'			
		]


primitiveLDAPConnectTo: host with: port 
| oop l |
self var: #l declareC: 'LDAPPluginT* l'.
self primitive: 'primitiveLDAPConnectTo'
	parameters: #(#String #SmallInteger).
interpreterProxy failed ifFalse: [
	oop _ interpreterProxy instantiateClass: interpreterProxy
		classByteArray indexableSize: self ldapRecordSize.
	l _ self ldapValueOf: oop.
	self sqLDAPConnectTo: l host: host hostlen: (host size) port: port.
	^ oop.
].


int sqLDAPConnectTohosthostlenport (LDAPPluginT* lp, char *hostname, int
hostlen, int port)
{
   vm = sqGetInterpreterProxy();
   
   lp->hostname = (char*) strndup (hostname, hostlen);   
   lp->port = port;
   lp->who = 0;
   lp->password = 0;
   lp->ldap = ldap_open (lp->hostname, lp->port);

   if (!lp->ldap) {
   	free (lp->hostname);
	lp->hostname = 0;
	vm->primitiveFail();	
   }						
	
   return 1;
}

I'm saving the different lp-> fields as I want to be able to keep using an
open ldap connection after an image reload.  If doing this will help or is a
better idea than what it looks like, I don't know yet.  It does help for
debugging.

> Andreas has already described how to call a finalizer on the Smalltalk 
> side. This would then call a primitive that would take the ByteArray 
> containing the handle and pass it back to the library cleanup 
> routine.

And a nice description for sure.  It feels weird to live in a land without
destructors  ;)
-- 
Ragnar Hojland - Project Manager
Linalco "Especialistas Linux y en Software Libre"
http://www.linalco.com Tel: +34-91-5970074 Fax: +34-91-5970083



More information about the Squeak-dev mailing list