[squeak-dev] Re: Multiple finalizers per single object

Igor Stasenko siguctua at gmail.com
Fri Sep 24 12:24:20 UTC 2010


2010/9/24 Levente Uzonyi <leves at elte.hu>:
> On Fri, 24 Sep 2010, Igor Stasenko wrote:
>
>> 2010/9/24 Levente Uzonyi <leves at elte.hu>:
>>>
>>> On Fri, 24 Sep 2010, Igor Stasenko wrote:
>>>
>>>> On 24 September 2010 01:40, Andreas Raab <andreas.raab at gmx.de> wrote:
>>>>>
>>>>> On 9/23/2010 3:27 PM, Igor Stasenko wrote:
>>>>>>
>>>>>> On 23 September 2010 23:58, Andreas Raab<andreas.raab at gmx.de>  wrote:
>>>>>>>
>>>>>>> Isn't that a bit of a made-up problem? I've never seen (nor heard of)
>>>>>>> anyone
>>>>>>> even trying to attach more than one finalizer to an object.
>>>>>>> Disallowing
>>>>>>> it
>>>>>>> could be done, but unless there's a good reason for it I'm not in
>>>>>>> favor
>>>>>>> of
>>>>>>> deciding what is good policy and what isn't without a practical use
>>>>>>> case
>>>>>>> at
>>>>>>> hand. If you have a use-case I'd like to hear more about it, but if
>>>>>>> not,
>>>>>>> then *shrug*, who cares :-)
>>>>>>>
>>>>>>
>>>>>> The practical use, that one may mistakenly add two same finalizers on
>>>>>> a same object,
>>>>>> like closing a file handle, or free external memory.
>>>>>> And it is potentially dangerous, because OS could reuse the same
>>>>>> memory location or file handle,
>>>>>> once you closed it, so, by closing it twice you can get a serious
>>>>>> trouble finding what's going on.
>>>>>>
>>>>>> My point, that if one ever needs a composite finalization action, a
>>>>>> WeakRegistry is wrong place for that.
>>>>>> WeakRegistry should prevent registering more than a signle finalizer
>>>>>> per unique object to prevent
>>>>>> potential problems which could arise from such composition(s).
>>>>>
>>>>> So you're saying one *could* do that and *if* one did that it *might*
>>>>> lead
>>>>> to a *potential* issue? Sounds like solving a non-problem to me :-)
>>>>>
>>>>
>>>> Yes i consider it as a potential security hole. It simply feels wrong to
>>>> me.
>>>> It is good that nobody using multiple finalizers.
>>>
>>> How do you know that for sure?
>>> Currently our announcement framework uses this feature to remove all weak
>>> subscriptions for an object when it's garbage collected. This avoids
>>> iterating through all the subscriptions looking for those which don't
>>> have a
>>> subscriber anymore. I'm sure it could be implemented another way, but
>>> it's
>>> really simple this way.
>>>
>> This is userful.
>> Though, iterating through all subscriptions, this is what you can
>> avoid using new finalization scheme.
>>
>> When weak field of subscription becomes nil, a subscription will be
>> automatically added to the list of expired subscriptions.
>> Then, after GC, you simply go through that list and remove them from
>> subscriptions container.
>> Note that such implementation doesn't involving WeakRegistry at all,
>> and therefore you won't be needing
>> multiple finalizers per single object.  :)
>
> I think we can live without multiple finalizers per object.
> Maybe the best solution is to make the behavior changeable when an object
> already has a finalizer in a WeakRegistry. With the current WeakRegistry
> this could be something like:
>
> WeakRegistry >> add: anObject executor: anExecutor
>        "Add anObject to the receiver. Store the object as well as the
> associated executor."
>
>        self protected: [
>                (valueDictionary associationAt: anObject ifAbsent: nil)
>                        ifNil: [ valueDictionary at: anObject put: anExecutor
> ]
>                        ifNotNil: [ :association |
>                                multipleFinalizerPerObjectAction
>                                        cull: association
>                                        cull: anExecutor ] ]
>
> WeakRegistry >> initialize: n
>
>        valueDictionary := WeakIdentityKeyDictionary new: n.
>        accessLock := Semaphore forMutualExclusion.
>        multipleFinalizerPerObjectAction := [ :association |
>                self error: association key printString, ' already has an
> executor!' ].
>        self installFinalizer.
>
> WeakRegistry >> multipleFinalizerPerObjectAction: aBlock
>
>        multipleFinalizerPerObjectAction := aBlock
>
>
> This way one could
> - have multiple finalizers per object as it is in Squeak 4.1
> - raise an error as you suggested
> - replace the current executor with the new one (as it was before Squeak
> 4.1).
>
> I don't know if it fits your new WeakRegistry implementation. I'm also not
> sure if this isn't a bit over-engineered.
>

I had to resemble same functionality, as in squeak 4.1 ,  so new
registry still supports
multiple finalizations per object.
Please, try to file-in the code in http://bugs.squeak.org/view.php?id=7473
and see if you have any problems with it.

>
> Levente
>
>>
>>>
>>> Levente
>>>
>>>> Okay, then why they are here? Code should have a practical use,
>>>> otherwise it is just a garbage, no?
>>>> Or is it an invitation to start using them?
>>>> I'm not envy to everyone who will start doing it. :)
>>>>
>>>> I'd really like to see a good practical example where such thing could
>>>> be userful,
>>>> which outweights a potential problems i described before.
>>>>
>>>>> (but go ahead and fix it if you feel that it needs fixing)
>>>>>
>>>>> Cheers,
>>>>>  - Andreas
>>>>>
>>>>>>
>>>>>>> Cheers,
>>>>>>>  - Andreas
>>>>>>>
>>>>>>> On 9/23/2010 1:23 PM, Igor Stasenko wrote:
>>>>>>>>
>>>>>>>> Hello,
>>>>>>>>
>>>>>>>> i'd like to raise this subject once more, because i don't like it
>>>>>>>> (or
>>>>>>>> don't understand?).
>>>>>>>>
>>>>>>>> In all scenarios, where i met the need to use finalization, a single
>>>>>>>> finalizer is sufficient.
>>>>>>>> Moreover, there is always a single object who controls a weak
>>>>>>>> reference, and it never leaks it out, to prevent
>>>>>>>> the case, when some other object may obtain a strong reference on
>>>>>>>> it,
>>>>>>>> making it permanently held in object memory.
>>>>>>>>
>>>>>>>> Multiple different finalizers for single object, from design point
>>>>>>>> of
>>>>>>>> view, means that you having two different, not related frameworks,
>>>>>>>> which using same object, and want to do something when it dies.
>>>>>>>> A scenario, where its possible and userful, still don't comes into
>>>>>>>> my
>>>>>>>> mind.
>>>>>>>> In contrary, whenever i see a use of finalizers, its in most cases
>>>>>>>> about graceful control over external resource, such as:
>>>>>>>> - file
>>>>>>>> - socket
>>>>>>>> - external memory
>>>>>>>>
>>>>>>>> and i really don't see how multiple finalizers per single resource
>>>>>>>> could do any good.
>>>>>>>>
>>>>>>>> Suppose one finalizer closing a file handle, while another one
>>>>>>>> flushing it buffer cache.
>>>>>>>> Now, how you going to ensure, that one finalizer will execute first,
>>>>>>>> before another one?
>>>>>>>> And what if third framework comes into play and wants to add another
>>>>>>>> finalizer on top of that, which should do something in the middle
>>>>>>>> between flushing a cache and closing file handle?
>>>>>>>>
>>>>>>>>>  From the above, the only conclusion can be made: use a single
>>>>>>>>
>>>>>>>> finalizer, and put all logic&    operation ordering into it.
>>>>>>>> And also, prevent leakage of object pointer (such as file handle)
>>>>>>>> outside of your model, otherwise it may cause harm.
>>>>>>>>
>>>>>>>> That's why i think a current WeakRegistry model provoking bad design
>>>>>>>> practices.
>>>>>>>> I think a better behavior would be to raise an error, if something
>>>>>>>> wants to register finalizer twice for a single object.
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Best regards,
>>>> Igor Stasenko AKA sig.
>>>>
>>>
>>>
>>>
>>>
>>
>>
>>
>> --
>> Best regards,
>> Igor Stasenko AKA sig.
>>
>
>
>
>



-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list