<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-size:small">Hi Jaromir,</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Feb 28, 2021 at 11:08 AM Jaromir Matas <<a href="mailto:m@jaromir.net">m@jaromir.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Hi, the following example shows a slight inconsistency in the process<br>
terminantion logic:<br>
<br>
   p := Process forContext: ([] asContextWithSender: thisContext) priority:<br>
40<br>
<br>
   p isTerminated   --> false<br>
<br>
   p terminate <br>
<br>
   p isTerminated   --> false<br>
<br>
<br>
I'm aware the example is nonsensical but I guess the terminate =><br>
isTerminated logic should be followed anyway.<br>
<br>
I propose the following change in the #isTerminated condition. The idea is<br>
if suspendedContext is the bottomContext and pc >= endPC then it should be<br>
considered terminated regardless of whether there is or isn't a closure. The<br>
rest of the condition remains intact. All tests green.<br>
<br>
I also suggest a new wording of the comment (the bottomContext block doesn't<br>
necessarily need to be the block in BlockClosure>>newProcess so I removed<br>
the note).<br>
<br>
The suggested version:<br>
<br>
isTerminated<br>
        "Answer if the receiver is terminated, or at least terminating."<br>
        self isActiveProcess ifTrue: [^ false].<br>
        ^suspendedContext isNil<br>
          or: ["If the suspendedContext is the bottomContext and the pc is at the<span class="gmail_default" style="font-size:small"> </span>endPC, <br>
                then there is nothing more to do."<br>
                suspendedContext isBottomContext<br>
                and: [suspendedContext pc >= suspendedContext endPC <br>
                                or: [suspendedContext closure<br>
                                                ifNil: [suspendedContext methodClass == Process<br>
                                                        and: [suspendedContext selector == #terminate]]<br>
                                                ifNotNil: [false]]]]<br>
<br>
<br></blockquote><div><br></div><div class="gmail_default" style="font-size:small">I like this.  But isn't this a little bit better?</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_quote">isTerminated</div><div class="gmail_quote"><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>"Answer if the receiver is terminated, or at least terminating."</div><div class="gmail_quote"><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>self isActiveProcess ifTrue: [^ false].</div><div class="gmail_quote"><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>^suspendedContext isNil</div><div class="gmail_quote"><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>  or: ["If the suspendedContext is the bottomContext and the pc is at the endPC, </div><div class="gmail_quote"><span class="gmail-Apple-tab-span" style="white-space:pre">         </span>then there is nothing more to do."</div><div class="gmail_quote"><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>suspendedContext isBottomContext</div><div class="gmail_quote"><span class="gmail-Apple-tab-span" style="white-space:pre">         </span>and: [suspendedContext pc >= suspendedContext endPC </div><div class="gmail_quote"><span class="gmail-Apple-tab-span" style="white-space:pre">                 </span>or: [suspendedContext closure isNil</div><div class="gmail_quote"><span class="gmail-Apple-tab-span" style="white-space:pre">                              </span>and: [suspendedContext methodClass == Process</div><div class="gmail_quote"><span class="gmail-Apple-tab-span" style="white-space:pre">                            </span>and: [suspendedContext selector == #terminate]]]]]</div><div class="gmail_default" style="font-size:small"></div><div class="gmail_default" style="font-size:small">I'm also tempted to state in a comment why being in other than a block in Process>>#terminate implies the methods is essentially done terminating.  And there in lies the rub, to quote Shakespeare.  Would a hack like adding a first temporary in Process>>#terminate called e.g. terminationStatus and having Process>>terminate assign to it when termination is essentially complete be better?</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">e.g.</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small"><div class="gmail_quote" style="color:rgb(0,0,0)">isTerminated</div><div class="gmail_quote" style="color:rgb(0,0,0)"><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>"Answer if the receiver is terminated, or at least terminating."</div><div class="gmail_quote" style="color:rgb(0,0,0)"><span class="gmail-Apple-tab-span" style="white-space:pre">    </span>self isActiveProcess ifTrue: [^ false].</div><div class="gmail_quote" style="color:rgb(0,0,0)"><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>^suspendedContext isNil</div><div class="gmail_quote" style="color:rgb(0,0,0)"><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>  or: ["If the suspendedContext is the bottomContext and the pc is at the endPC, </div><div class="gmail_quote" style="color:rgb(0,0,0)"><span class="gmail-Apple-tab-span" style="white-space:pre">             </span>then there is nothing more to do."</div><div class="gmail_quote" style="color:rgb(0,0,0)"><span class="gmail-Apple-tab-span" style="white-space:pre">               </span>suspendedContext isBottomContext</div><div class="gmail_quote" style="color:rgb(0,0,0)"><span class="gmail-Apple-tab-span" style="white-space:pre">              </span>and: [suspendedContext pc >= suspendedContext endPC </div><div class="gmail_quote" style="color:rgb(0,0,0)"><span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>or: [suspendedContext closure isNil</div><div class="gmail_quote" style="color:rgb(0,0,0)"><span class="gmail-Apple-tab-span" style="white-space:pre">                           </span>and: [suspendedContext methodClass == Process</div><div class="gmail_quote" style="color:rgb(0,0,0)"><span class="gmail-Apple-tab-span" style="white-space:pre">                         </span>and: [suspendedContext selector == #terminate</div><div class="gmail_quote" style="color:rgb(0,0,0)"><span class="gmail-Apple-tab-span" style="white-space:pre">                         </span>and: [(suspendedContext localAt: 1) == #terminated]]]]]]</div></div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default"><div class="gmail_default" style="font-size:small">terminate </div><div class="gmail_default"><span class="gmail-Apple-tab-span" style="font-size:small;white-space:pre">      </span>"<font face="arial, sans-serif">Stop the process that the receiver represents forever.</font></div><div class="gmail_default"><font face="arial, sans-serif"><span class="gmail-Apple-tab-span" style="white-space:pre">        </span> Unwind to execute pending ensure:/ifCurtailed: blocks before terminating.</font></div><div class="gmail_default"><font face="arial, sans-serif"><span class="gmail-Apple-tab-span" style="white-space:pre"> </span> If the process is in the middle of a critical: critical section, release it properly.</font></div><div class="gmail_default"><font face="arial, sans-serif"><span class="gmail-Apple-tab-span" style="color:rgb(0,0,0);white-space:pre">    </span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(0,0,0)">N.B. </span><span style="color:rgb(0,0,0)">terminationStatus is for the benefit of Process>>#isTerminated</span><span style="color:rgb(0,0,0)">.</span>"</font></div><div class="gmail_default" style="color:rgb(0,0,0)"></div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>| terminationStatus ctxt unwindBlock oldList |</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">       </span>self isActiveProcess ifTrue:</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">         </span>[ctxt := thisContext.</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">                </span> [ctxt := ctxt findNextUnwindContextUpTo: nil.</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">               </span>  ctxt ~~ nil] whileTrue:</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">                   </span>[(ctxt tempAt: 2) ifNil:</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">                             </span>["N.B. Unlike Context>>unwindTo: we do not set complete (tempAt: 2) to true."</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">                                </span> unwindBlock := ctxt tempAt: 1.</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">                              </span> thisContext terminateTo: ctxt.</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">                              </span> unwindBlock value]].</div><div class="gmail_default" style="color:rgb(0,0,0)"><font face="arial, sans-serif"><span class="gmail-Apple-tab-span" style="white-space:pre">>>>            </span>terminationStatus := #terminated.</font></div><div class="gmail_default" style="color:rgb(0,0,0)"></div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">             </span>thisContext terminateTo: nil.</div><div class="gmail_default"><font face="arial, sans-serif"><span class="gmail-Apple-tab-span" style="white-space:pre">           </span>self suspend.</font></div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">           </span>"If the process is resumed this will provoke a cannotReturn: error.</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">             </span> Would self debug: thisContext title: 'Resuming a terminated process' be better?"</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">               </span>^self].</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">   </span>"Always suspend the process first so it doesn't accidentally get woken up.</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">  </span> N.B. If oldList is a LinkedList then the process is runnable. If it is a Semaphore/Mutex et al</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">      </span> then the process is blocked, and if it is nil then the process is already suspended."</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">  </span>oldList := self suspend.</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">     </span>suspendedContext ifNotNil:</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">           </span>["Release any method marked with the <criticalSection> pragma.</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">            </span>  The argument is whether the process is runnable."</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">            </span> self releaseCriticalSection: (oldList isNil or: [oldList class == LinkedList]).</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>"If terminating a process halfways through an unwind, try to complete that unwind block first."</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">            </span>(suspendedContext findNextUnwindContextUpTo: nil) ifNotNil:</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">                  </span>[:outer|</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">                     </span> (suspendedContext findContextSuchThat:[:c| c closure == (outer tempAt: 1)]) ifNotNil:</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">                               </span>[:inner| "This is an unwind block currently under evaluation"</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">                              </span> suspendedContext runUntilErrorOrReturnFrom: inner]].</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="color:rgb(0,0,0)"><span class="gmail-Apple-tab-span" style="font-family:arial,sans-serif;white-space:pre">>>>           </span><span style="font-family:arial,sans-serif">terminationStatus := #terminated</span><span style="font-family:arial,sans-serif">.</span></div><div class="gmail_default" style="color:rgb(0,0,0)"></div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>ctxt := self popTo: suspendedContext bottomContext.</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>ctxt == suspendedContext bottomContext ifFalse:</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">                      </span>[self debug: ctxt title: 'Unwind error during termination'].</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">         </span>"Set the context to its endPC for the benefit of isTerminated."</div><div class="gmail_default" style="font-size:small"><span class="gmail-Apple-tab-span" style="white-space:pre">            </span>ctxt pc: ctxt endPC]</div><div class="gmail_default" style="font-size:small"><br></div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
-----<br>
^[^ Jaromir<br>
--<br>
Sent from: <a href="http://forum.world.st/Squeak-Dev-f45488.html" rel="noreferrer" target="_blank">http://forum.world.st/Squeak-Dev-f45488.html</a><br>
</blockquote></div><div><br></div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>