[squeak-dev] Re: [Pharo-project] #ensure: issues

Igor Stasenko siguctua at gmail.com
Thu Mar 4 00:19:13 UTC 2010

On 4 March 2010 01:56, Nicolas Cellier
<nicolas.cellier.aka.nice at gmail.com> wrote:
> 2010/3/4 Levente Uzonyi <leves at elte.hu>:
>> On Thu, 4 Mar 2010, Nicolas Cellier wrote:
>>> 2010/3/3 Levente Uzonyi <leves at elte.hu>:
>>>> On Wed, 3 Mar 2010, Andreas Raab wrote:
>>>>> On 3/3/2010 2:07 PM, Levente Uzonyi wrote:
>>>>>> On Wed, 3 Mar 2010, Igor Stasenko wrote:
>>>>>>> i don't get it. Just before that, you said: ' I'd expect it to be
>>>>>>> evaluated no matter what happens.' ?
>>>>>>> But now you saying that it may not be executed in some conditions
>>>>>>> (when user pressing abandon button, causing process to be terminated).
>>>>>> It's simple: don't terminate process X from another process if process
>>>>>> X
>>>>>> is executing a termiation block (aka #ensure: block). Or if you
>>>>>> terminate it, make sure that the execution of the block will continue
>>>>>> somehow (I don't care how).
>>>>> You're missing Igors point which is that in his example the halt /
>>>>> Transcript *was* in the ensure block and as a result you're
>>>>> contradicting
>>>>> yourself here. Let's go back to Igor's example:
>>>>> [self boom ] ensure: [ self halt. Transcript show: 'boom']
>>>>> The halt is inside the ensure block. If you terminate the process from
>>>>> the
>>>>> debugger, it would be logical from your statement that the Transcript
>>>>> message would be executed - after all it's " executing a termiation
>>>>> block
>>>>> (aka #ensure: block)" and so it can't be terminated by your reasoning.
>>>>> However, when Igor was pointing this out you replied with "I didn't say
>>>>> that. I said evaluate it the same way as normal code." which is
>>>>> inconsistent
>>>>> with the other statement.
>>>> That shows my lack of knowledge about how the debugger works.
>>>>>> I think every user of #ensure: expects that the termination blocks are
>>>>>> executed even if the process which is executing the receiver of
>>>>>> #ensure:
>>>>>> is terminated. And it actually happens in all but this case.
>>>>> The question of terminating processes is always tricky. I don't think
>>>>> that
>>>>> your proposal would actually work in practice - it could easily result
>>>>> in
>>>>> processes that cannot be terminated due to a simple bug in an ensure
>>>>> block.
>>>>> Personally, I'd rather say that the more useful behavior would be
>>>>> something
>>>>> along the lines of saying that process termination either skips the
>>>>> current
>>>>> ensure block (assuming there's a bug and it should get the heck out of
>>>>> it
>>>>> but try to evaluate the remaining ones) or that there need to be two
>>>>> terminations - one that is 'soft' and won't allow ensure blocks to be
>>>>> skipped and one that is 'hard' (kill -9 hard) and just ignores all the
>>>>> ensure blocks.
>>>> I'm only saying that normal usage (aka #terminate) shouldn't do
>>>> unexpected
>>>> things like this.
>>>> If you read the comment of Process >> #terminate, you may assume that
>>>> #ensure: and #ifCurtailed: blocks will be excuted even if you use
>>>> #terminate, but that's not true.
>>>> "Stop the process that the receiver represents forever.  Unwind to
>>>> execute
>>>> pending ensure:/ifCurtailed: blocks before terminating."
>>>> Levente
>>> The only way I see to solve your problem would be to execute the
>>> unwind block in another process...
>>> Quite technical and costly !
>> It's our problem. Just look at the senders of #ensure: and imagine what will
>> happen if the termination block is not evaluated.
>> I think there's another way (though it might be my lack of knowledge again).
>> After suspending the process which is about to be terminated we can check if
>> it's executing a termination block. It it's not, we are safe to continue the
>> termination, otherwise we can do something else which ensures that the
>> termination block is evaluated.
> Maybe...
> Unfortunately, you did not tell how you will distinguish well behaved
> unwind-blocks from Igor's example...

Yes, then what prevents me from writing:

[ [ ] ensure: [ self doCrazyThings ] ] fork.

and now given assumption that any code which placed inside ensure
block should always run to the end, without chances being terminated,
will have ill side effects.
The #ensure: means, that interpreter will have a chance to enter that
block eventually, but it should not mean that it will keep running the
code there until normal or non-local return from that block.
Othewise, you losing a way to terminate unwanted, ill-behaved process.

> Nicolas
>> Levente
>>> Nicolas
>>>>> Cheers,
>>>>>  - Andreas

Best regards,
Igor Stasenko AKA sig.

More information about the Squeak-dev mailing list