Hi,
if you examine the following example you'll notice only the innermost unwind context currently under evaluation will get completed during termination. But the unwind contexts may be nested so I guess we should attempt completing the outermost context rather than the innermost only. | p | p := [ [ ] ensure: [ [ ] ensure: [Processor activeProcess suspend. Transcript show: 'x1']. Transcript show: 'x2'] ] fork. Processor yield. p terminate Expected output: x1 x2 Real output: x1 (`Processor activeProcess suspend` models a situation a process gets suspended and then for whatever reason terminated) This is the current implementation within #teminate: "If terminating a process halfways through an unwind, try to complete that unwind block first." (suspendedContext findNextUnwindContextUpTo: nil) ifNotNil: [:outer| (suspendedContext findContextSuchThat:[:c| c closure == (outer tempAt: 1)]) ifNotNil: [:inner| "This is an unwind block currently under evaluation" suspendedContext runUntilErrorOrReturnFrom: inner]]. I'm proposing this modification: "If terminating a process halfways through an unwind, try to complete that unwind block first." ctxt := suspendedContext. [ctxt := ctxt findNextUnwindContextUpTo: nil. ctxt ~~ nil] whileTrue: [outerMost := ctxt]. outerMost ifNotNil: ["This is the bottom-most unwind context currently under evaluation; now let's find the currently context executing its argument block (tempAt: 1)" (suspendedContext findContextSuchThat: [:c | c closure == (outerMost tempAt: 1)]) ifNotNil: [:inner | suspendedContext runUntilErrorOrReturnFrom: inner]]. Changeset: Process-terminate_modify_outerMost.st <http://forum.world.st/file/t372955/Process-terminate_modify_outerMost.st> Other bugs in terminate (and related): [1] http://forum.world.st/Bug-in-Process-gt-gt-terminate-Returning-from-unwind-contexts-td5127570.html [2] http://forum.world.st/The-Inbox-Kernel-jar-1376-mcz-td5127335.html#a5127372 [3] http://forum.world.st/Refactoring-terminate-to-get-rid-of-cannot-return-errors-etc-td5127732.html (The last is a part of my effort to refactor termination to at least deal with the current bugs) ----- ^[^ Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html
^[^ Jaromir
|
Unfortunately there's one more bug in #terminate:
The existing code fails to execute unwind blocks after completing the innermost unwind block. Examine the following example nesting two unwind blocks halfway through execution and one outer unwind block not started yet: | p | p := [ [ [ ] ensure: ["x2" [ ] ensure: ["x1" Processor activeProcess suspend. Transcript show: 'x1']. Transcript show: 'x2'] ] ensure: ["x3" Transcript show: 'x3'] ] fork. Processor yield. p terminate ---> x1 (only!) Process p is suspended halfway through an unwind block x1 and is terminated - you'd expect #terminate to finish the unfinished unwind blocks x1 and x2 and execute an outer unwind block x3. But the result is only x1 is completed and both x2 and x3 are ignored! The reason x3 is ignored is that #runUntilErrorOrReturnFrom: resets suspendedContext sender to nil so the rest of the code is doing nothing useful. The fix is to update suspendedContext after #runUntilErrorOrReturnFrom is returned from. Process >> terminate "..." ctxt := suspendedContext. [ctxt := ctxt findNextUnwindContextUpTo: nil. ctxt ~~ nil] whileTrue: [(ctxt tempAt:2) ifNotNil: [outerMost := ctxt]]. outerMost ifNotNil: ["This is the bottom-most unwind context currently under evaluation; now let's find the currently context executing its argument block (tempAt: 1)" (suspendedContext findContextSuchThat: [:c | c closure == (outerMost tempAt: 1)]) ifNotNil: [:inner | suspendedContext runUntilErrorOrReturnFrom: inner. "update suspendedContext" suspendedContext := outerMost]]. "..." Now the test example returns 'x1 x2 x3' as expected. Updated changeset enclosed: Process-terminate_modify_outerMost_v2.st <http://forum.world.st/file/t372955/Process-terminate_modify_outerMost_v2.st> Thanks for your comments. ----- ^[^ Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html
^[^ Jaromir
|
This issue has been fixed - see the discussion at
http://forum.world.st/Solving-multiple-termination-bugs-summary-amp-proposal-td5128285.html ----- ^[^ Jaromir -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html
^[^ Jaromir
|
Free forum by Nabble | Edit this page |