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! 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? Cheers, Balázs & Levente > > *yay > Henry* > * > |
2010/3/2 Levente Uzonyi <[hidden email]>:
> 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? > > 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. > Cheers, > Balázs & Levente > > >> >> *yay >> Henry* >> * > > > > -- Best regards, Igor Stasenko AKA sig. |
On Tue, 2 Mar 2010, Igor Stasenko wrote:
> 2010/3/2 Levente Uzonyi <[hidden email]>: > 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? > > 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. Levente > Cheers, > Balázs & Levente > > >> >> *yay >> Henry* >> * > > > > -- Best regards, Igor Stasenko AKA sig. _______________________________________________ Pharo-project mailing list [hidden email] http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project |
2010/3/3 Levente Uzonyi <[hidden email]>:
> On Tue, 2 Mar 2010, Igor Stasenko wrote: > >> 2010/3/2 Levente Uzonyi <[hidden email]>: >> 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. > [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 > [hidden email] > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project > > > -- Best regards, Igor Stasenko AKA sig. |
On Wed, 3 Mar 2010, Igor Stasenko wrote:
> 2010/3/3 Levente Uzonyi <[hidden email]>: >> On Tue, 2 Mar 2010, Igor Stasenko wrote: >> >>> 2010/3/2 Levente Uzonyi <[hidden email]>: >>> 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 > > >> >> Levente >> >> >>> Cheers, >>> Balázs & Levente >>> >>> >>>> >>>> *yay >>>> Henry* >>>> * >>> >>> >>> >>> >> >> >> >> -- >> Best regards, >> Igor Stasenko AKA sig. >> >> _______________________________________________ >> Pharo-project mailing list >> [hidden email] >> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project >> >> >> > > > > -- > Best regards, > Igor Stasenko AKA sig. > > |
2010/3/3 Levente Uzonyi <[hidden email]>:
> On Wed, 3 Mar 2010, Igor Stasenko wrote: > >> 2010/3/3 Levente Uzonyi <[hidden email]>: >>> >>> On Tue, 2 Mar 2010, Igor Stasenko wrote: >>> >>>> 2010/3/2 Levente Uzonyi <[hidden email]>: >>>> 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'] > > Yes. > print 'boom' in transcript? > > Levente > >> >> >>> >>> Levente >>> >>> -- Best regards, Igor Stasenko AKA sig. |
On Wed, 3 Mar 2010, Igor Stasenko wrote:
> 2010/3/3 Levente Uzonyi <[hidden email]>: >> On Wed, 3 Mar 2010, Igor Stasenko wrote: >> >>> 2010/3/3 Levente Uzonyi <[hidden email]>: >>>> >>>> On Tue, 2 Mar 2010, Igor Stasenko wrote: >>>> >>>>> 2010/3/2 Levente Uzonyi <[hidden email]>: >>>>> 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'] >> >> Yes. >> > so, even if you click 'abandon' in debugger popup, its still should > print 'boom' in transcript? evaluate this code: self halt. Transcript show: 'boom'. and press abandon, then Transcript show: 'boom' will not be executed. Levente > >> >> Levente >> >>> >>> >>>> >>>> Levente >>>> >>>> > > > > > -- > Best regards, > Igor Stasenko AKA sig. > > |
2010/3/3 Levente Uzonyi <[hidden email]>:
> On Wed, 3 Mar 2010, Igor Stasenko wrote: > >> 2010/3/3 Levente Uzonyi <[hidden email]>: >>> >>> On Wed, 3 Mar 2010, Igor Stasenko wrote: >>> >>>> 2010/3/3 Levente Uzonyi <[hidden email]>: >>>>> >>>>> On Tue, 2 Mar 2010, Igor Stasenko wrote: >>>>> >>>>>> 2010/3/2 Levente Uzonyi <[hidden email]>: >>>>>> 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'] >>> >>> Yes. >>> >> so, even if you click 'abandon' in debugger popup, its still should >> print 'boom' in transcript? > > I didn't say that. I said evaluate it the same way as normal code. Please define, what is 'normal' code. If you maybe know, exceptions and stack unwinding implemented in smalltalk, there's no any 'magic' and this code interpreted by VM as any other code, which makes it as 'normal' as any other one. > If you evaluate this code: > > self halt. Transcript show: 'boom'. > > and press abandon, then Transcript show: 'boom' will not be executed. > 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). > > Levente > >> >>> >>> Levente >>> >>>> >>>> >>>>> >>>>> Levente >>>>> >>>>> >> >> >> >> >> -- >> Best regards, >> Igor Stasenko AKA sig. >> > > > > -- Best regards, Igor Stasenko AKA sig. |
On Wed, 3 Mar 2010, Igor Stasenko wrote:
> 2010/3/3 Levente Uzonyi <[hidden email]>: >> On Wed, 3 Mar 2010, Igor Stasenko wrote: >> >>> 2010/3/3 Levente Uzonyi <[hidden email]>: >>>> >>>> On Wed, 3 Mar 2010, Igor Stasenko wrote: >>>> >>>>> 2010/3/3 Levente Uzonyi <[hidden email]>: >>>>>> >>>>>> On Tue, 2 Mar 2010, Igor Stasenko wrote: >>>>>> >>>>>>> 2010/3/2 Levente Uzonyi <[hidden email]>: >>>>>>> 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'] >>>> >>>> Yes. >>>> >>> so, even if you click 'abandon' in debugger popup, its still should >>> print 'boom' in transcript? >> >> I didn't say that. I said evaluate it the same way as normal code. > > Please define, what is 'normal' code. If you maybe know, exceptions > and stack unwinding implemented in smalltalk, there's no any 'magic' > and this code interpreted by VM as any other code, which makes it as > 'normal' as any other one. > >> If you evaluate this code: >> >> self halt. Transcript show: 'boom'. >> >> and press abandon, then Transcript show: 'boom' will not be executed. >> > > 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). 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). 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. Levente > >> >> Levente >> >>> >>>> >>>> Levente >>>> >>>>> >>>>> >>>>>> >>>>>> Levente >>>>>> >>>>>> >>> >>> >>> >>> >>> -- >>> Best regards, >>> Igor Stasenko AKA sig. >>> >> >> >> >> > > > > -- > Best regards, > Igor Stasenko AKA sig. > > |
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. > 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. Cheers, - Andreas |
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 > > Cheers, > - Andreas > > |
2010/3/3 Levente Uzonyi <[hidden email]>:
> 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 ! Nicolas >> >> Cheers, >> - Andreas >> >> > > |
On Thu, 4 Mar 2010, Nicolas Cellier wrote:
> 2010/3/3 Levente Uzonyi <[hidden email]>: >> 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 ! 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. Levente > > Nicolas > >>> >>> Cheers, >>> - Andreas >>> >>> >> >> > > |
2010/3/4 Levente Uzonyi <[hidden email]>:
> On Thu, 4 Mar 2010, Nicolas Cellier wrote: > >> 2010/3/3 Levente Uzonyi <[hidden email]>: >>> >>> 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... Nicolas > > Levente > >> >> Nicolas >> >>>> >>>> Cheers, >>>> - Andreas >>>> >>>> >>> >>> >> > > > > |
On Thu, 4 Mar 2010, Nicolas Cellier wrote:
> 2010/3/4 Levente Uzonyi <[hidden email]>: >> On Thu, 4 Mar 2010, Nicolas Cellier wrote: >> >>> 2010/3/3 Levente Uzonyi <[hidden email]>: >>>> >>>> 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... which are safe to evaluate. So I assume that all such blocks behave well. If something goes wrong you can kill the process with a more aggressive method (as Andreas suggested), but you lose the guarantee that the current termination block will be evaluated. Levente > > Nicolas > >> >> Levente >> >>> >>> Nicolas >>> >>>>> >>>>> Cheers, >>>>> - Andreas >>>>> >>>>> >>>> >>>> >>> >> >> >> >> > > |
In reply to this post by Nicolas Cellier
On 4 March 2010 01:56, Nicolas Cellier
<[hidden email]> wrote: > 2010/3/4 Levente Uzonyi <[hidden email]>: >> On Thu, 4 Mar 2010, Nicolas Cellier wrote: >> >>> 2010/3/3 Levente Uzonyi <[hidden email]>: >>>> >>>> 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. |
In reply to this post by Levente Uzonyi-2
2010/3/4 Levente Uzonyi <[hidden email]>:
> On Thu, 4 Mar 2010, Nicolas Cellier wrote: > >> 2010/3/4 Levente Uzonyi <[hidden email]>: >>> >>> On Thu, 4 Mar 2010, Nicolas Cellier wrote: >>> >>>> 2010/3/3 Levente Uzonyi <[hidden email]>: >>>>> >>>>> 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... > > I'd give the responsibility to the developer to write termination blocks > which are safe to evaluate. So I assume that all such blocks behave well. If > something goes wrong you can kill the process with a more aggressive > method (as Andreas suggested), but you lose the guarantee that the current > termination block will be evaluated. > > > Levente > I would tend to focus first on the senders of terminate since terminating is unsafe... How many of them would deserve to be transformed in a terminateRequest ? Nicolas >> >> Nicolas >> >>> >>> Levente >>> >>>> >>>> Nicolas >>>> >>>>>> >>>>>> Cheers, >>>>>> - Andreas >>>>>> >>>>>> >>>>> >>>>> >>>> >>> >>> >>> >>> >> > > > > |
In reply to this post by Andreas.Raab
2010/3/3 Andreas Raab <[hidden email]> On 3/3/2010 2:07 PM, Levente Uzonyi wrote: That's what we did in VisualWorks. Normal terminate is as you say. It tries to run unwinds until an error, and then if necessary one wields terminateWithExtremePrejudice and kills the thing stone dead.
|
In reply to this post by Nicolas Cellier
On Thu, 4 Mar 2010, Nicolas Cellier wrote:
> 2010/3/4 Levente Uzonyi <[hidden email]>: >> On Thu, 4 Mar 2010, Nicolas Cellier wrote: >> >>> 2010/3/4 Levente Uzonyi <[hidden email]>: >>>> >>>> On Thu, 4 Mar 2010, Nicolas Cellier wrote: >>>> >>>>> 2010/3/3 Levente Uzonyi <[hidden email]>: >>>>>> >>>>>> 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... >> >> I'd give the responsibility to the developer to write termination blocks >> which are safe to evaluate. So I assume that all such blocks behave well. If >> something goes wrong you can kill the process with a more aggressive >> method (as Andreas suggested), but you lose the guarantee that the current >> termination block will be evaluated. >> >> >> Levente >> > > I would tend to focus first on the senders of terminate since > terminating is unsafe... evaluate the termination blocks. Levente > How many of them would deserve to be transformed in a terminateRequest ? > > Nicolas > >>> >>> Nicolas >>> >>>> >>>> Levente >>>> >>>>> >>>>> Nicolas >>>>> >>>>>>> >>>>>>> Cheers, >>>>>>> - Andreas >>>>>>> >>>>>>> >>>>>> >>>>>> >>>>> >>>> >>>> >>>> >>>> >>> >> >> >> >> > > |
In reply to this post by Eliot Miranda-2
2010/3/4 Eliot Miranda <[hidden email]>:
> > > 2010/3/3 Andreas Raab <[hidden email]> >> >> 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. >> >>> 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. > > That's what we did in VisualWorks. Normal terminate is as you say. It > tries to run unwinds until an error, and then if necessary one wields > terminateWithExtremePrejudice and kills the thing stone dead. Fun name. I just imagine a terminateWithGradualPrejudice that would step to next unwind block in case of error... Nicolas >> >> Cheers, >> - Andreas >> > > > > > |
Free forum by Nabble | Edit this page |