[Pharo-project] [squeak-dev] #ensure: issues (was: Re: Pharo by Example vol 2: new chapter available)

Igor Stasenko siguctua at gmail.com
Wed Mar 3 15:57:02 UTC 2010


2010/3/3 Levente Uzonyi <leves at elte.hu>:
> On Tue, 2 Mar 2010, Igor Stasenko wrote:
>
>> 2010/3/2 Levente Uzonyi <leves at elte.hu>:
>> On Tue, 2 Mar 2010, Henrik Sperre Johansen wrote:
>>
>>>
>>>>> PS. For the not-so-faint-of-heart, open a Transcript and try
>>>>> evaluating:
>>>>> |proc|
>>>>> proc := [[Transcript show: 'Start!'. ] ensure: [Transcript show:
>>>>> 'Finish!' Processor yield.]] newProcess.
>>>>> proc resume.
>>>>> Processor yield.
>>>>> proc suspend.
>>>>> proc terminate.
>>>>
>>>> Why don't we get it printing?
>>>
>>> Forgot a . there, supposed to be
>>>
>>> |proc|
>>> proc := [[Transcript show: 'Start!'. ] ensure: [Transcript show:
>>> 'Finish!'. Processor yield.]] newProcess.
>>> proc resume.
>>> Processor yield.
>>> proc suspend.
>>> proc terminate.
>>>
>>> on my machine it prints:
>>> *Start!Start!Finish!
>>
>> The problem occurs because Transcript >> #endEntry (sent from #show:)
>> takes a while to execute, so the process (proc) prints 'Start!', but
>> it gets terminated before execution reaches #resetContents (#reset in
>> Squeak). So 'Start!' is still in the stream. Then our process executes the
>> #ensure: block and it prints 'Start!' and 'Finish!' too.
>>
>> There's worse problem with #ensure: and #terminate is that, a process
>> executing an #ensure: block can be terminated. If you evaluate this code:
>>
>> | process stage1 stage2 stage3 counter |
>> stage1 := stage2 := stage3 := false.
>> counter := 0.
>> process := [
>>        [ stage1 := true ] ensure: [
>>                stage2 := true.
>>                1000000 timesRepeat: [ counter := counter + 1 ].
>>                stage3 := true ] ] newProcess.
>> process resume.
>> Processor yield.
>> process suspend.
>> process terminate.
>> 1000 milliSeconds asDelay wait.
>> { stage1. stage2. stage3. counter } explore
>>
>> you will find that stage1 and stage2 is reached as expected, but stage3 is
>> not and counter is less than 1000000. That's because the forked process
>> started evaluating the #ensure: block, but it was terminated by our
>> process.
>>
>> Is this the expected behavior when sending #terminate to a process which
>> is
>> evaluating an #ensure: block?
>>
>>
> What you think is expected behavior here:
>
> a) process termination should start (be triggered) only when process
> is outside of any #ensure: closure?
> b) #ensure: block should always run to the end, despite anything?
>
> Since you can't predict, what code will run inside ensure block, the
> only guarantee that you having is actually
> that your process will always enters such blocks during the normal
> flow, or exception handling. But there is no guarantees that it will
> be able to run the code inside it, when you terminating it.
>
>
> I'd expect it to be evaluated no matter what happens.
>
even this one?
[self boom ] ensure: [ self halt. Transcript show: 'boom']


>
> Levente
>
>
>> Cheers,
>> Balázs & Levente
>>
>>
>>>
>>> *yay
>>> Henry*
>>> *
>>
>>
>>
>>
>
>
>
> --
> 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 Squeak-dev mailing list