[Pharo-project] [squeak-dev] Re: WeakRegistry>>remove: - when you'll be in trouble

Igor Stasenko siguctua at gmail.com
Sun Oct 10 20:33:28 EDT 2010


2010/10/11 Levente Uzonyi <leves at elte.hu>:
> On Mon, 11 Oct 2010, Igor Stasenko wrote:
>
>> On 10 October 2010 23:43, Levente Uzonyi <leves at elte.hu> wrote:
>> On Sun, 10 Oct 2010, Igor Stasenko wrote:
>>
>>> A current implementation of this method
>>>
>>> remove: oldObject ifAbsent: exceptionBlock
>>>        "Remove oldObject as one of the receiver's elements."
>>>
>>>        oldObject ifNil: [ ^nil ].
>>>        ^(self protected: [ valueDictionary removeKey: oldObject ifAbsent:
>>> nil ])
>>>                ifNil: [ exceptionBlock value ]
>>>
>>> simply removes a previously registered object from registry and voila.
>>>
>>> Now lets get back to our discussion about multiple finalizers per
>>> object and using them in weak subscriptions etc.
>>>
>>> Suppose i am added a socket to weak registry,
>>> and suppose i am added a weak subscription to it.
>>>
>>> Now, if i do 'socket close' , it tells weak registry to remove it from
>>> list.
>>> And what we'll have:
>>> - socket handle is closed
>>> - socket is wiped from weak registry
>>> - but weak subscription still listed somewhere in a list of subscriptions
>>>
>>>
>>> My suggestion is, that upon #remove:,
>>> a weak registry should notify all executors that object of interest
>>> are no longer takes part in finalization scheme,
>>> so they should not count on receiving #finalize eventually.
>>>
>>> In other words:
>>>
>>> remove: oldObject ifAbsent: exceptionBlock
>>>        "Remove oldObject as one of the receiver's elements."
>>>
>>>        oldObject ifNil: [ ^nil ].
>>>        ^(self protected: [ | executor |
>>>            executor := valueDictionary removeKey: oldObject ifAbsent:
>>> nil.
>>>            executor discardFinalization.
>>>        ])
>>>        ifNil: [ exceptionBlock value ]
>>
>> It's only an issue with the new WeakRegistry implementation, previous
>> implementations don't have such problem. I think changing the method as
>> you
>> suggested, implementing WeakFinalizerItem >> #discardFinalization as
>> "executor := nil" and changing WeakFinalizerItem >> #finalizaValues to
>> ignore the executor if it's nil will fix the problem. Am I right?
>>
>> I don't get how "multiple finalizers per object" is related to this
>> problem
>> at all.
>>
>
> No, you miss the point.
> When you removing object from weak registry, it is important , time to
> time to tell all of its executors,
> that they will no longer receive #finalize, because object is no
> longer a member of weak registry.
>
> If you simply set executor := nil, it does nothing, an executor itself
> did not notified that he won't be needed
> in any possible future.
> So, if your finalization action is to remove some object(s) from the
> list , you'll get your list dirty after object will die,
> because #finalize will be never sent to your executor.
>
> Here the simple test case:
>
> | coll obj someWrapper |
> coll := OrderedCollection new.
> obj := Object new.
> someWrapper := WeakArray with: obj.
> coll add: someWrapper.
>
> obj toFinalizeSend: #remove: to: coll with: someWrapper.
> obj finalizationRegistry remove: obj.
> obj := nil.
> Smalltalk garbageCollect.
> self assert: coll isEmpty
>
>
> the point is, that once you doing a #remove: ,
> your finalization scheme is broken.
>
>
> I don't get you. When you remove an object from a WeakRegistry, you tell the
> system that you want the object removed and all related executors deleted.
> So the executors should never receive #finalize, they should be thrown away.
> Even if there's action to be done with the executors (which is pointless
> IMHO since those will be thrown away, but who knows), doing them is the
> responsibility of the sender of #remove:.
>

Let us get back to multiple finalizers per object,
when you have two separate places, which adding possibly different
executors for a single object
without knowing about each other (otherwise why would you want to add
two finalizers instead of one).
Now if one decides to do #remove: ,
how to ensure that second one won't be left with dirty/invalid state?

>
> Levente
>
>>
>> Levente
>>
>
> --
> Best regards,
> Igor Stasenko AKA sig.
>
> _______________________________________________
> Pharo-project mailing list
> Pharo-project at lists.gforge.inria.fr
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>
>
>



-- 
Best regards,
Igor Stasenko AKA sig.




More information about the Pharo-dev mailing list