[Pharo-project] [NB] Problem with releasing a NBExternalObject
Hello, I have a subclass of NBExternalObject to refer to an external object (from the ICU library). When I'm done with the object I need to close it. The following instance method takes care of this: primClose <primitive: #primitiveNativeCall module: #NativeBoostPlugin> self nbCall: #( void ucal_close( ICUCalendarNB self ) ) This works fine. But now I want to make use of the NBExternalResourceManager so that external objects are closed automatically when they are no longer referenced. For this I have implemented the required instance method: resourceData ^ handle And the class methods: finalizeResourceData: aHandle Transcript show: 'Closing ', aHandle printString ; cr. aHandle isNull ifFalse: [ self primClose: aHandle ] and primClose: aHandle <primitive: #primitiveNativeCall module: #NativeBoostPlugin> ^ self nbCall: #( void ucal_close( void* aHandle ) ) But now two things are going wrong: - The #finalizeResourceData: doesn't seem to get called - If I call the #primClose: directy with the handle as an argument my Image crashes. Is the signature of the #nbCall: message wrong? Jan. PS: I'm using the latest NB-Cog-VM from https://ci.lille.inria.fr/pharo/view/Cog/
On 24 August 2012 14:54, Jan van de Sandt <jvdsandt@gmail.com> wrote:
Hello,
I have a subclass of NBExternalObject to refer to an external object (from the ICU library). When I'm done with the object I need to close it. The following instance method takes care of this:
primClose <primitive: #primitiveNativeCall module: #NativeBoostPlugin> self nbCall: #( void ucal_close( ICUCalendarNB self ) )
This works fine. But now I want to make use of the NBExternalResourceManager so that external objects are closed automatically when they are no longer referenced. For this I have implemented the required instance method:
resourceData
^ handle
And the class methods:
finalizeResourceData: aHandle
Transcript show: 'Closing ', aHandle printString ; cr. aHandle isNull ifFalse: [ self primClose: aHandle ]
and
primClose: aHandle <primitive: #primitiveNativeCall module: #NativeBoostPlugin> ^ self nbCall: #( void ucal_close( void* aHandle ) )
But now two things are going wrong: - The #finalizeResourceData: doesn't seem to get called
perhaps because you still got a strong references to that object somewhere?
- If I call the #primClose: directy with the handle as an argument my Image crashes.
Ok it looks like a typical mistake, (which i also do from time to time ;) .. by passing a pointer to value instead of value itself. Here, a handle is a variable-byte object, holding a value (4 bytes) so, if you pass it as argument of following type: void* aHandle you will actually not pass the value of handle itself, but a pointer to a first byte in memory where that value held. To fix that try following: resourceData ^ handle value primClose: aHandleValue <primitive: #primitiveNativeCall module: #NativeBoostPlugin> ^ self nbCall: #( void ucal_close( uint aHandleValue ) )
Is the signature of the #nbCall: message wrong?
Jan.
PS: I'm using the latest NB-Cog-VM from https://ci.lille.inria.fr/pharo/view/Cog/
-- Best regards, Igor Stasenko.
Hello Igor, Thanks for the explanation. Closing via the class method now works fine! But I still notice that the #finalizeResourceData doesn't get called. The instance is already gone because the #allInstances method returns an empty collection. Strange .... Jan. PS: I installed NB in a new 1.4 image this afternoon. Some tests failed because the Integer>>#& method was missing. Probably is should be part of the AsmJit-Extension package. After I added this method the tests worked again. On Fri, Aug 24, 2012 at 3:38 PM, Igor Stasenko <siguctua@gmail.com> wrote:
On 24 August 2012 14:54, Jan van de Sandt <jvdsandt@gmail.com> wrote:
Hello,
I have a subclass of NBExternalObject to refer to an external object (from the ICU library). When I'm done with the object I need to close it. The following instance method takes care of this:
primClose <primitive: #primitiveNativeCall module: #NativeBoostPlugin> self nbCall: #( void ucal_close( ICUCalendarNB self ) )
This works fine. But now I want to make use of the NBExternalResourceManager so that external objects are closed automatically when they are no longer referenced. For this I have implemented the required instance method:
resourceData
^ handle
And the class methods:
finalizeResourceData: aHandle
Transcript show: 'Closing ', aHandle printString ; cr. aHandle isNull ifFalse: [ self primClose: aHandle ]
and
primClose: aHandle <primitive: #primitiveNativeCall module: #NativeBoostPlugin> ^ self nbCall: #( void ucal_close( void* aHandle ) )
But now two things are going wrong: - The #finalizeResourceData: doesn't seem to get called
perhaps because you still got a strong references to that object somewhere?
- If I call the #primClose: directy with the handle as an argument my Image crashes.
Ok it looks like a typical mistake, (which i also do from time to time ;) .. by passing a pointer to value instead of value itself. Here, a handle is a variable-byte object, holding a value (4 bytes) so, if you pass it as argument of following type:
void* aHandle
you will actually not pass the value of handle itself, but a pointer to a first byte in memory where that value held.
To fix that try following:
resourceData ^ handle value
primClose: aHandleValue <primitive: #primitiveNativeCall module: #NativeBoostPlugin> ^ self nbCall: #( void ucal_close( uint aHandleValue ) )
Is the signature of the #nbCall: message wrong?
Jan.
PS: I'm using the latest NB-Cog-VM from https://ci.lille.inria.fr/pharo/view/Cog/
-- Best regards, Igor Stasenko.
On 24 August 2012 15:55, Jan van de Sandt <jvdsandt@gmail.com> wrote:
Hello Igor,
Thanks for the explanation. Closing via the class method now works fine!
But I still notice that the #finalizeResourceData doesn't get called. The instance is already gone because the #allInstances method returns an empty collection. Strange ....
i will write a test for finalization registry to see if it works.. should be working, but who knows :)
Jan.
PS: I installed NB in a new 1.4 image this afternoon. Some tests failed because the Integer>>#& method was missing. Probably is should be part of the AsmJit-Extension package. After I added this method the tests worked again.
rrrrrr.... this is because some very nice guy put those methods into Pharo 2.0 kernel. now things are messy, since in 1.4 you still need those methods as extension, but in 2.0 you don't need them, because if they present, loading NB will mark kernel package dirty :( this can be solved by adding an extra pharo-14-compat package and writing a configuration in a way that it will load that package in 1.4 but not in 2.0.. but this is tedious, and frankly i didn't learned well, how to do that trick with metacello. -- Best regards, Igor Stasenko.
Igor, On 24 Aug 2012, at 16:01, Igor Stasenko <siguctua@gmail.com> wrote:
this can be solved by adding an extra pharo-14-compat package and writing a configuration in a way that it will load that package in 1.4 but not in 2.0.. but this is tedious, and frankly i didn't learned well, how to do that trick with metacello.
Next week we are going to build such a package (that adds methods to 1.3 or 1.4 so that lib writers can better follow new 2.0 api, I need it for Zn too). Sven
Thanks! I'm sorry to be a bit out since a couple of months but I'm trying to get back on shape. Stef
this can be solved by adding an extra pharo-14-compat package and writing a configuration in a way that it will load that package in 1.4 but not in 2.0.. but this is tedious, and frankly i didn't learned well, how to do that trick with metacello.
Next week we are going to build such a package (that adds methods to 1.3 or 1.4 so that lib writers can better follow new 2.0 api, I need it for Zn too).
Sven
On 24 August 2012 15:55, Jan van de Sandt <jvdsandt@gmail.com> wrote:
Hello Igor,
Thanks for the explanation. Closing via the class method now works fine!
But I still notice that the #finalizeResourceData doesn't get called. The instance is already gone because the #allInstances method returns an empty collection. Strange ....
btw did you added a call to #registerAsExternalResource in instance initialization method somewhere (once you have initialized handle of course)? because of course, if you don't register it, a finalization will never be called.
Jan.
PS: I installed NB in a new 1.4 image this afternoon. Some tests failed because the Integer>>#& method was missing. Probably is should be part of the AsmJit-Extension package. After I added this method the tests worked again.
On Fri, Aug 24, 2012 at 3:38 PM, Igor Stasenko <siguctua@gmail.com> wrote:
On 24 August 2012 14:54, Jan van de Sandt <jvdsandt@gmail.com> wrote:
Hello,
I have a subclass of NBExternalObject to refer to an external object (from the ICU library). When I'm done with the object I need to close it. The following instance method takes care of this:
primClose <primitive: #primitiveNativeCall module: #NativeBoostPlugin> self nbCall: #( void ucal_close( ICUCalendarNB self ) )
This works fine. But now I want to make use of the NBExternalResourceManager so that external objects are closed automatically when they are no longer referenced. For this I have implemented the required instance method:
resourceData
^ handle
And the class methods:
finalizeResourceData: aHandle
Transcript show: 'Closing ', aHandle printString ; cr. aHandle isNull ifFalse: [ self primClose: aHandle ]
and
primClose: aHandle <primitive: #primitiveNativeCall module: #NativeBoostPlugin> ^ self nbCall: #( void ucal_close( void* aHandle ) )
But now two things are going wrong: - The #finalizeResourceData: doesn't seem to get called
perhaps because you still got a strong references to that object somewhere?
- If I call the #primClose: directy with the handle as an argument my Image crashes.
Ok it looks like a typical mistake, (which i also do from time to time ;) .. by passing a pointer to value instead of value itself. Here, a handle is a variable-byte object, holding a value (4 bytes) so, if you pass it as argument of following type:
void* aHandle
you will actually not pass the value of handle itself, but a pointer to a first byte in memory where that value held.
To fix that try following:
resourceData ^ handle value
primClose: aHandleValue <primitive: #primitiveNativeCall module: #NativeBoostPlugin> ^ self nbCall: #( void ucal_close( uint aHandleValue ) )
Is the signature of the #nbCall: message wrong?
Jan.
PS: I'm using the latest NB-Cog-VM from https://ci.lille.inria.fr/pharo/view/Cog/
-- Best regards, Igor Stasenko.
-- Best regards, Igor Stasenko.
On Fri, Aug 24, 2012 at 4:29 PM, Igor Stasenko <siguctua@gmail.com> wrote:
On 24 August 2012 15:55, Jan van de Sandt <jvdsandt@gmail.com> wrote:
Hello Igor,
Thanks for the explanation. Closing via the class method now works fine!
But I still notice that the #finalizeResourceData doesn't get called. The instance is already gone because the #allInstances method returns an empty collection. Strange ....
btw did you added a call to #registerAsExternalResource in instance initialization method somewhere (once you have initialized handle of course)? because of course, if you don't register it, a finalization will never be called.
Yes I did. If I inspect the registry instVar of NBExternalResourceManager>>#soleInstance than there are a lot of items present.
Jan.
PS: I installed NB in a new 1.4 image this afternoon. Some tests failed because the Integer>>#& method was missing. Probably is should be part of the AsmJit-Extension package. After I added this method the tests worked again.
On Fri, Aug 24, 2012 at 3:38 PM, Igor Stasenko <siguctua@gmail.com> wrote:
On 24 August 2012 14:54, Jan van de Sandt <jvdsandt@gmail.com> wrote:
Hello,
I have a subclass of NBExternalObject to refer to an external object (from the ICU library). When I'm done with the object I need to close it.
The
following instance method takes care of this:
primClose <primitive: #primitiveNativeCall module: #NativeBoostPlugin> self nbCall: #( void ucal_close( ICUCalendarNB self ) )
This works fine. But now I want to make use of the NBExternalResourceManager so that external objects are closed automatically when they are no longer referenced. For this I have implemented the required instance method:
resourceData
^ handle
And the class methods:
finalizeResourceData: aHandle
Transcript show: 'Closing ', aHandle printString ; cr. aHandle isNull ifFalse: [ self primClose: aHandle ]
and
primClose: aHandle <primitive: #primitiveNativeCall module: #NativeBoostPlugin> ^ self nbCall: #( void ucal_close( void* aHandle ) )
But now two things are going wrong: - The #finalizeResourceData: doesn't seem to get called
perhaps because you still got a strong references to that object somewhere?
- If I call the #primClose: directy with the handle as an argument my Image crashes.
Ok it looks like a typical mistake, (which i also do from time to time ;) .. by passing a pointer to value instead of value itself. Here, a handle is a variable-byte object, holding a value (4 bytes) so, if you pass it as argument of following type:
void* aHandle
you will actually not pass the value of handle itself, but a pointer to a first byte in memory where that value held.
To fix that try following:
resourceData ^ handle value
primClose: aHandleValue <primitive: #primitiveNativeCall module: #NativeBoostPlugin> ^ self nbCall: #( void ucal_close( uint aHandleValue ) )
Is the signature of the #nbCall: message wrong?
Jan.
PS: I'm using the latest NB-Cog-VM from https://ci.lille.inria.fr/pharo/view/Cog/
-- Best regards, Igor Stasenko.
-- Best regards, Igor Stasenko.
On 24 August 2012 16:52, Jan van de Sandt <jvdsandt@gmail.com> wrote:
On Fri, Aug 24, 2012 at 4:29 PM, Igor Stasenko <siguctua@gmail.com> wrote:
On 24 August 2012 15:55, Jan van de Sandt <jvdsandt@gmail.com> wrote:
Hello Igor,
Thanks for the explanation. Closing via the class method now works fine!
But I still notice that the #finalizeResourceData doesn't get called. The instance is already gone because the #allInstances method returns an empty collection. Strange ....
btw did you added a call to #registerAsExternalResource in instance initialization method somewhere (once you have initialized handle of course)? because of course, if you don't register it, a finalization will never be called.
Yes I did. If I inspect the registry instVar of NBExternalResourceManager>>#soleInstance than there are a lot of items present.
Okay, there is a bug indeed.. stupid wrong selector (as usual).. try replacing 'item finalize' with 'item finalizeValues' in NBFinalizationRegistry>>finalizeValues method i will upload a fix and tests meanwhile. Thanks for pointing out! -- Best regards, Igor Stasenko.
ok, i uploaded the fix. it is in v 1.3. so if you reload this version of ConfigurationOfNativeBoost, it should install the fixed latest versions of packages. -- Best regards, Igor Stasenko.
Thanks Igor. A small bug is not really a problem if it gets fixed so quickly. NativeBoost is really cool technology! Jan. On Fri, Aug 24, 2012 at 5:44 PM, Igor Stasenko <siguctua@gmail.com> wrote:
ok, i uploaded the fix. it is in v 1.3. so if you reload this version of ConfigurationOfNativeBoost, it should install the fixed latest versions of packages.
-- Best regards, Igor Stasenko.
2012/8/24 Jan van de Sandt <jvdsandt@gmail.com>
Thanks Igor.
NativeBoost is really cool technology!
yes! Thanks Igor to document it. I will read the doc soon and give you feedback. Luc
Jan.
On Fri, Aug 24, 2012 at 5:44 PM, Igor Stasenko <siguctua@gmail.com> wrote:
ok, i uploaded the fix. it is in v 1.3. so if you reload this version of ConfigurationOfNativeBoost, it should install the fixed latest versions of packages.
-- Best regards, Igor Stasenko.
participants (5)
-
Igor Stasenko -
Jan van de Sandt -
Luc Fabresse -
Stéphane Ducasse -
Sven Van Caekenberghe