Hi, 

sorry for arriving so late to this, but I was on holidays :)
this is how autoRelease works: 

1) #autoRelease of an object registers object for finalisation with a 
particular executor. Then behaviour is divided: 

2.1.1) for ExternalAddresses, it just registers in regular way, who will call 
#finalize on GC
2.1.2) finalize will just call a free assuming ExternalAddress was allocated 
(which is a malloc)

2.2.1) for all FFIExternalReference, it will register for finalisation what 
#resourceData answers (normally, the handle of the object)
2.2.2) finalisation process will call the object class>>#finalizeResourceData: 
method, with the #resourceData result as parameter
2.2.3) each kind of external reference can decide how to free that data (by 
default is also just freeing). 

An example of this is how CairoFontFace works (or AthensCairoSurface). 

In you case, you will have something like: 

FFIExternalObject subclass: #CXString

CXString class>>#finalizeResourceData: version
        self ffiCall: #(void clang_disposeString(void *version))

notice that here I casted to void*… this is because actually resourceData 
answers a pointer, not the object.

cheers, 
Esteban


> On 06 Sep 2016, at 13:29, Ben Coman <b...@openinworld.com> wrote:
> 
> Hi Pierce,
> 
> I can't determine from DemoFFI how the autorelease works.
> 
> I see memory is allocated by the C library here....
>  DemoFFIAutoThing>>allocByReturnedPointer
>    super allocByReturnedPointer.
>    handle autoRelease
> 
> where super is...
>  DemoFFIThing>>allocByReturnedPointer
>    ((handle := DemoFFILibrary uniqueInstance apiAllocByReturnedPointer) 
> isNull)
>        ifTrue: [ DemoFFIError signal: 'bummer' ]
> 
> and...
>  DemoFFILibrary>>apiAllocByReturnedPointer
>    "demo_thing* alloc_by_returned_pointer(void)"
>    ^ self ffiCall: #(DemoFFIExternalObject alloc_by_returned_pointer ())
> 
> 
> which I guess is to be released by...
>  DemoFFILibrary>>apiFree: handle
>    "int free_thing(demo_thing*)"
>    ^ self ffiCall: #(int free_thing (DemoFFIExternalObject handle))
> 
> but this has only one sender...
>    DemoFFIThing>>letGo
>        handle isNull ifFalse: [
>           DemoFFILibrary uniqueInstance apiFree:  handle ]
> 
> and the only sender of #letGo is...
>    DEMOFFIThingTest >> tearDown
> 
> From this I can't follow how  #apiFree:  ultimately gets automatically
> invoked by the object finalization.  Are you able to fill me in on the
> details?
> 
> cheers -ben
> 
> 
> On Sun, Sep 4, 2016 at 10:40 PM, Ben Coman <b...@openinworld.com> wrote:
>> On Fri, Sep 2, 2016 at 10:04 PM, Pierce Ng <pie...@samadhiweb.com> wrote:
>>> On Fri, Sep 02, 2016 at 12:40:06PM +0800, Ben Coman wrote:
>>>> Referring to the example show_clang_version() below, cleanup is done
>>>> with clang_disposeString(). How does UFFI hook into the object
>>>> finalisation mechanism to call this when the object is garage
>>>> collected.
>>> 
>>> Ben, see if this addresses your query:
>>> 
>>>  http://www.samadhiweb.com/blog/2016.03.12.demoffi.html
>>> 
>>> Pierce
>>> 
>> 
>> Thanks Pierce.  I've loaded DemoFFI and browsing it now.
>> autorelease looks like part of what I need.
>> I guess it is #finalize where I should call the libraryAPI_free() function?
>> 
>> cheers -ben
> 


Reply via email to