FWIW, this quote from the following discussion on Squeak-dev distills
what I was trying (but failing) to demonstrate:
"We shouldn't stop trying to support well-behaved ensure blocks
properly.
Because if we don't then ensure
becomes entirely random. Or can anyone here explain why it would be
reasonable to expect that this version works:
p := [[Processor yield] ensure:[Transcript show: 'finished']] fork.
Processor yield.
p terminate.
but this one doesn't:
p := [[] ensure:[Processor yield. Transcript show: 'finished']] fork.
Processor yield.
p terminate.
(we're using yield here to denote any kind of process switch) If the
only thing that determines whether an ensure block is executed is a
process switch, then we basically have random, non-predictable unwind
handling. Which is a problem that is entirely unrelated to whether the
unwind block is itself well-behaved or not. "
In a book with chapters discussing topics such as ensure and processes,
(based on Pharo 1.0 which is unlikely to contain any fixes for such an
issue), it deserves at least a mention.
Cheers,
Henry
Den 03.03.2010 15:33, skrev Levente Uzonyi:
On Wed, 3 Mar 2010, St�phane Ducasse wrote:
On Mar 2, 2010, at 10:33 PM, Levente Uzonyi wrote:
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.
Thanks for the explanation levente!
But I'm still dizzy :) why Transcript show: 'Finish' would also print
'start' ?
Transcript is just a stream. #show: is just a combination of
#nextPutAll: and #endEntry. #endEntry displays the contents of the
stream and when that's done it removes everything from the stream with
#resetContents. #resetContents is never executed, because the process
is terminated before that. So the contents of the stream are kept and
displayed again later.
Levente
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?
Cheers,
Bal�zs & Levente
*yay
Henry*
*
_______________________________________________
Pharo-project mailing list
Pharo-project@lists.gforge.inria.fr
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________
Pharo-project mailing list
Pharo-project@lists.gforge.inria.fr
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project