On Fri, Jan 8, 2016 at 9:40 PM, Henrik Johansen <henrik.s.johansen@veloxit.no> wrote:
Here's an alternative implementation, which, instead of checking for the new method name, hooks into the existing unwind machinery to execute the waitIfCurtailed: argument. Which removes the special case from Process >> #terminate, but at the added cost that in-progress unwinds are executed as if the (suspended) terminating thread they started executing on, is still the active process. (Which, arguably, should be done anyways)
It feels a bit fragile playing peeking into "Processor activeProcess suspendingList". Also it doesn't work :) It is not sufficient to test with only two processes. You need three, since it is the third process that wakes up incorrectly. lock := Semaphore forMutualExclusion. waitInFirstCritical := Semaphore new. Transcript clear; show: 'excessSignals=' , (lock instVarNamed: 'excessSignals') printString. testBlock := [ :n | Transcript crShow: n printString , ' start'. lock critical2: [ (n=1) ifTrue: [ waitInFirstCritical wait ]. Transcript crShow: n printString, ' done'. ]]. proc1 := (testBlock newProcessWith: {1}) priority: 50. proc2 := (testBlock newProcessWith: {2}) priority: 50. proc3 := (testBlock newProcessWith: {3}) priority: 50. proc1 resume. proc2 resume. proc3 resume. "proc2 terminate." waitInFirstCritical signal. Transcript cr; show: 'excessSignals=' , (lock instVarNamed: 'excessSignals') printString. "proc2 terminate" commented produces the expected result... excessSignals=1 1 start 2 start 3 start 1 done 2 done 3 done excessSignals=1 "proc2 terminate" uncommented produces incorrect ordering... excessSignals=1 1 start 2 start 3 start 3 done "<--should occur after 1" 1 done excessSignals=2 "<--should be 1" Now using "lock := CriticalSection new" provided by Eliot (and removing instVarNamed: 'excessSignals' access from the test script) produces correct result... 1 start 2 start 3 start 1 done 3 done cheers -ben