[Pharo-project] [squeak-dev] Re: Another finalization concern: error handling

Levente Uzonyi leves at elte.hu
Mon Oct 11 10:47:18 EDT 2010


On Mon, 11 Oct 2010, Igor Stasenko wrote:

> On 11 October 2010 16:51, Levente Uzonyi <leves at elte.hu> wrote:
> On Mon, 11 Oct 2010, Igor Stasenko wrote:
>
>> Hello,
>>
>> here a situation, with which we can deal in more safer manner:
>>
>> Suppose you have a weak registry, populated by different objects and
>> their executors.
>>
>> Now, when some of them died, a weak registry performs finalization.
>>
>> The potential danger is , that if there's an error triggered by some
>> executor(s),
>> then rest of executors will have no chance to run and will be
>> forgotten, causing memory leakage.
>>
>> What you think, should we handle this more graciously?
>>
>> (Consider a following meta-code)
>>
>> WeakRegistry>>finalizeValues
>> | executors |
>>  executors := self gatherExecutorsToRun.
>>
>>  executors do: [:ex |
>>    [ ex finalize ] fork.
>>  ].
>
> The "gatherExecutorsToRun" part was implemented in the previous version of
> WeakRegistry (history is not available from the image...). #finalize wasn't
> sent from the protected block. The current version lacks it, so it will
> deadlock if a finalizer will try to access the same WeakRegistry. Other kind
> of deadlocks are also possible. For example when a finalizer can access a
> semaphore which is also used by another process that uses the same semaphore
> and also uses the WeakRegistry, but locks them in a different order
> (JNIPort).
> This only happens if the VM doesn't support the new finalization scheme
> which is the case for most current VMs.
>
> There is another issue with removal, and this affects the new finalization
> scheme too, because the finalizer of valuesDictionary is #finalizeValues.
> This means that finalization can happen in a process other than the
> finalization process. This can lead to random errors.
>
err no. valuesDictionary are held privately by weak registry. and any
access to it possible only
through instance of weak registry, which always using protect: [].


Hm. You missed the point. When someone sends #remove: to the WeakRegistry, 
it will send #removeKey:ifAbsent to valuesDictionary. If valuesDictionary 
has an association in the removed element's chain which key was garbage 
collected, then it will be finalized. (See WeakKeyDictionary >> 
#removeKey:ifAbsent:). Since the currently installed finalizer is 
#finalizeValues, the finalization will be done by a process other than the 
finalization process.

> So I think parts of the old WeakRegistry implementation should be restored,
> like:
> - WeakRegistry should collect executors
> - executors should be evaluated outside the protected block
>
agreed on this one.

But weak registry lost this feature before my intervention:

This is a code from Squeak 4.1. image:
finalizeValues
 	"Some of our elements may have gone away. Look for those and activate
the associated executors."
 	self protected: [ valueDictionary finalizeValues ]

ul 2/22/2010 14:23 ˙˙ finalization ˙˙ 2 implementors ˙˙ in no change set ˙˙

So, i thought, it not a big sacrifice, besides it runs faster.
And to my thinking, the code which needs to manipulate weak registry
during finalization smells badly.


I was talking about the code in the Squeak 4.2 code.

>>
>> in this way, if any executor's #finalize causing error, it won't
>> interfere with other executors, and they will accomplish their task
>> normally.
>> Of course, i'm not saying that we should use #fork for this, because
>> it is costly. Similar could be done w/o forking.
>> I just wanted to show a simplest code with which we could achieve a
>> more gracious error handling.
>
> Wouldn't it be better to use an exception handler?
>

Well, its a bit complicated, since what i want is to:

  - report an error
  - but continue run #finalize for rest executors

or:

  - report an error (stop finalization process), then
  - continue running for next executor , if user press 'abandon'
  - or continue with running fixed code

If i'm not mistaken, currently, if you put halt inside a finalization
process (like in some #finalize method) and then abandon it,
you won't have finalization process in system anymore, because it will
be terminated.


That's right. I more like the first version, because not all systems are 
interactive. Stopping the finalization process for a long time cause a lot 
of problems. Btw, WeakArray >> #finalizationProcess has a similar issue.


Levente

>
> Levente
>
>>
>> P.S. of course, in a first place it would be good to make sure that we
>> writing executors, which can't cause an error during finalization.
>> But bad things happen, and we should make sure that rest of system
>> won't be put on its knees because of some stupid bug in a single
>> #finalize.
>>
>> --
>> 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.

_______________________________________________
Pharo-project mailing list
Pharo-project at lists.gforge.inria.fr
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


More information about the Pharo-dev mailing list