[Vm-dev] [ENH] A better finalization support (VM & language side)

Levente Uzonyi leves at elte.hu
Wed Mar 10 02:34:40 UTC 2010


On Tue, 9 Mar 2010, Igor Stasenko wrote:

>
> 2010/3/9 Levente Uzonyi <leves at elte.hu>:
>>
>> On Tue, 9 Mar 2010, Igor Stasenko wrote:
>>
>>> Well, if someone cares, then he actually can make own registry class,
>>> which allows copying. But why we should care, by leaving a potential
>>> security hole open?
>>> I don't think that this is normal to rely on good manners of users and
>>> expect them to not attempt to do something wrong. In contrast, a
>>> protocols and interfaces should discourage user from abuse. At least,
>>> an author could state where it is safe to use and where is not.
>>> A copy protocol for weak registry is far from being safe.
>>> In that situation is better to generate an error, indicating that such
>>> use is not foreseen by author, rather than trying to implement
>>> something which 'possibly could work' :)
>>
>> I still don't see how is it unsafe.
>>
>
> A simple copy is fine. A copy, which then registered in weak
> dependents creating a problem.
>
> I even think that weak registry should not behave as collection at all,
> and having only #add: method, with no ability to remove items.
>
> The only use of #remove: i see is in Socket and StandardFileStream,
> which implement #unregister: in own class side.
>
> Now , if you look at my implementation, you could see that there is a
> way to completely avoid the need in removing items from a
> valueDictionary which is pairs of  <weakref> -> <executor>.
>
> A solution:
> - add a 'finalizer' ivar to Socket/StandardFileStream
> - by registering a socket in registry, retrieve an instance of
> WeakFinalizerItem as a result of registration and store it into
> 'finalizer' ivar.
>
> - on #destroy, simply nil-out all of the finalizer's ivars, so there
> is no chances that once socket become garbage, it will trigger an
> executor's #finalize method, which were registered previously in
> registry.
>
> - forget about removing the finalizer manually from registry, because
> an instance of WeakFinalizerItem which is held by 'valueDictionary' in
> registry will eventually be reclaimed, once dictionary will discover
> that corresponding key is nil.
>
> What you think?

I took a deeper look and found that WeakFinalizationRegistry doesn't 
support multiple finalizers per object. It does what WeakRegistry did 
before: throw away the previous finalizer and replace it with a new one.

I like the current features of WeakRegistry (removing, adding, multiple 
finalizers per object) and I think it's easy to modify it to use your vm 
support.

I don't really like your suggestion for files and sockets, but it's 
doable.

I was thinking about a simpler registry which would use an 
OrderedCollection instead of a WeakKeyDictionary. It'd need a new 
instance variable in WeakFinalizerItem (though it can be another 
class/subclass too) which would store the index of the finalizer in this 
OrderedCollection. It wouldn't have #do:, #keys or #remove:ifAbsent: 
(though all of them could be implemented) and #add: wouldn't replace 
existing finalizers, but just add them to the registry.
This would have a bit better performance, simpler implementation and less 
features. But if you don't need #remove:, i'm sure it'd fit your needs.
(It's a bit tricky though. Your socket/file ideas wouldn't work out of the 
box, because all of the WeakFinalizerItems would have to be removed from 
the OrderedCollecion somehow to avoid leaking memory. One solution would 
be to add it to the list on "remove" (when replacing the ivars with nil), 
another would be to remove it from the OrderedCollection by index, 
but the items don't know their collection so it would need another ivar).

All in all, I'd keep WeakRegistry with the current features and optionally 
add a new simpler and faster registry if needed.


Levente

>
>>
>> Levente
>>
>
>
> -- 
> Best regards,
> Igor Stasenko AKA sig.
>


More information about the Vm-dev mailing list