[squeak-dev] The semantics of halfway-executed unwind contexts during process termination

mail at jaromir.net mail at jaromir.net
Thu Dec 16 22:37:23 UTC 2021


Hi Eliot,

Many thanks for your comments; it'll take me some time to respond properly and with reasonable arguments but let me just briefly touch some points I think you may be mistaken (in the text below):
best,
~~~
^[^    Jaromir

Sent from Squeak Inbox Talk

On 2021-12-16T14:20:01-08:00, eliot.miranda at gmail.com wrote:

> Hi Jaromir,
> 
>     I'm responding to this message because you introduce useful
> categorisation of different kinds of terminate. I'll respond in context
> below.
> 

> > One more naming suggestion:
> > (iii) terminate (~run all unwind blocks)
> > (ii) terminateLessSafely (~skip unwind blocks in progress, run all
> > not-yet-started ones)
> > (i) terminateUnsafely (~kill, run no unwinds)
> >
> 
> OK, this is really useful.  It provides the straight-forward options we
> have for process termination.  Now let's try and be categorical about
> unwind blocks.
> 
> Unwind blocks are used to maintain invariants.  The classic example is
> Semaphore>>critical:
> 
> critical: mutuallyExcludedBlock
>     "Evaluate mutuallyExcludedBlock only if the receiver is not currently in
>      the process of running the critical: message. If the receiver is,
> evaluate
>      mutuallyExcludedBlock after the other critical: message is finished."
>     <criticalSection>
>     self wait.
>     ^mutuallyExcludedBlock ensure: [self signal]
> 
> Given that unwind blocks are used to maintain invariants, any terminate
> which does (iii), run all unwind blocks, including those that have already
> been run, is completely broken.  

I think this is a misunderstanding: it was never intended to run an unwind block twice; the point was to *finish* unwind blocks that were in the middle of their execution; never re-run.

> We can therefore ignore (i). It would run
> unwinds more than once.   The correct terminate is (ii). Skip unwind blocks
> already in progress. Presumably something very wrong has happened in an
> unwind block that has not completed.  But all unwinds further away from top
> of stack should and must be run normally.  Note that in the normal case
> there will be no such partial unwinds; it will not occur in correct code.
> Note further that its extremely unlikely that there will be an unwind
> within an unwind.
> 
> But there's an assumption here.  In normal termination, unwind blocks will
> just run, and the process will terminate cleanly.  If it terminates itself
> then there is no issue other than potential bugs in unwinds (likely during
> development, rather than normal running).  An application that wants to
> terminate other processes should be written to terminate those processes it
> needs to only when those processes are at some safe point.  I would not
> spend effort trying to make terminate safe when sent from other processes
> at arbitrary points.  That counts as trying to shoot oneself in the foot.

Fair point, I did it as a learning exercise :)

> 
> So terminate boils down to two or three cases, depending on how you look at
> it.  The first case, or pair of cases, is a process that terminates itself
> or is terminated by another process while at a safe point.  In this case
> any and all unwinds *must* be run. The final case is a process that is
> stuck in termination, presumably due to a bug in an unwind.  This is the
> only point where we have the choice between ii and i.
> 
> So IMO the choice should be between terminate (ii) and
> terminateUnsafely (i). [I believe that in VisualWorks I called (i)
> terminateWithExtremePrejudice, after Apocalypse Now].  

Current VisualWorks use all three termination modes and unfortunately renamed them to boring:
(iii) terminate
(ii) terminateUnsafely
(i) terminateUnsafelyNow

The semantics is very similar to what's being proposed here though, i.e. #terminate tries to finish all *unfinished* unwind blocks in progress (even nested).
#terminateUnsafely unwinds only blocks that haven't started yet and is used as a debugger Abandon action and #terminateUnsafelyNow just kills.

> When a process
> starts to terminate, it is marked somehow as being terminated, running
> unwind blocks.  If the normal terminate is sent to the process while in
> this state that terminate send should raise an error; attempting to
> terminate a process twice is an error.  

Yes, this another bug I found in current #terminate; it allows teminating again a process being currently terminated and also allows to resume a process that is being terminated. I'll be sending some tests and suggestion how to fix it.

>We cannot automatically decide if a
> process in this state is correctly running unwinds; that would be
> equivalent to solving the halting problem.  Therefore we leave it up to the
> programmer to decide if, on discovering a terminating process stuck
> somewhere in running unwinds, they terminateUnsafely.
> 
> A key attitude here is to make the common case work well.  Don't let the
> perfect be the enemy of the good.  In this case there is no perfect
> solution; arbitrary errors *can* occur, *potentially*, in termination, but
> in practice are extremely rare.  Keeping the system simple, comprehensible
> and maintainable is a prime directive.  If a programmer can, for example,
> use the debugger to manually run undins that have not yet run because of a
> stuck unwind, then there is no absolute need for the system to handle this
> situation gracefully.  A developer that gets themselves in hot water
> creating errors iu unwinds can get themselves out using the debugger.
> 
> So for me, KISS.  

Agreed, absolutely... The only BUT from me is to fix bugs making learning a miserable experience :)

>Just support something that guards against multiple
> termination, 

As I said, I'll send tests and a solution for your consideration.

> and in the debugger, reveals clearly where a process is in the
> course of running unwinds.
> 
> And I really *don'* like the idea of running terminate in a separate
> process.  

I'm sorry to hear that indeed :D  

> This has bad performance implications.  Most terminations can be
> done in the process itself; that should be the expectation.
> 
> 
> > Marcel wrote:
> >
> > > How would you summarize the differences between #terminate,
> > #terminateAggressively, and #kill, each with 1-2 sentences? :-)
> >
> > Inspired by VW:
> >
> > (iii) "Terminate the process and allow all unwind blocks to run, even if
> > they are currently in progress." This is the behavior we expect when
> > terminating a healthy process.
> >
> > (ii) "Terminate the process and run all not-yet-started unwind blocks; if
> > the process is in the middle of an unwind block, then that unwind block
> > will not be completed, but subsequent unwind blocks will be run." This is
> > the behavior we expect when we close the debugger in a situation when the
> > unwind block may not be able to complete, either because of an error, or
> > because it is hung. In most other circumstances, we would want to use
> > #terminate, which allows unwind blocks in progress to complete.
> >
> > (i) "Terminate the process without attempting to run any of its unwind
> > blocks." This is the behavior we might need in very rare circumstances when
> > modes (iii) and (ii) fail.
> >
> > Changeset:
> >
> > > Please find the attached changeset in which I have changed the names
> > accordingly and also have removed the kill/destroy operation from the UI as
> > per request of Marcel. I aggree with his argument that destroy is a kind of
> > private operation that affects the interna of the process and should be
> > only used for troubleshooting, so we should not give this hack too much
> > visibility.
> >
> > Nice! I liked your Abandon button with options more but this is a start.
> > Kill option: do you mean no access to the kill option from the Process
> > browser either? Process browser is a very troubleshooting tool :)
> >
> > And finally, If I may - I'd slightly prefer not adding another #terminate:
> > to the Process class only to serve a single sender but rather inline it and
> > address the two termination modes directly in the ProcessBrowser class:
> >
> >
> > ProcessBrowser class >> #terminateProcess: aProcess aggressively:
> > aggressive
> >
> >         aProcess ifNil: [^ self].
> >
> >         self suspendedProcesses
> >                 removeKey: aProcess
> >                 ifAbsent: [].
> > -       aProcess terminate: aggressive.
> > +       aggressive
> >                 ifFalse: [aProcess terminate]
> >                 ifTrue: [aProcess terminateAggressively]
> >
> >
> > > Concerning your #unwindTo: issue - not sure if this actually related to
> > this thread? Actually I've lost the overview which terminate mode - (ii) or
> > (iii) - you are referring to, maybe we should discuss this in a separate
> > conversation. :-)
> >
> > Yes, it's a bug and deserves its own thread.
> >
> > ===
> > Summary:
> >
> > > TLDR: Concerning our next steps - consider this a small to-do list:
> > >
> > > - [ ] We want to implement three modi of process termination:
> > >   - [x] (i) is not yet implemented but should be easy to implement
> > >   - [x] (ii) is in my proposal from [2], maybe needs further refinement
> > >   - [ ] (iii) is pretty much what we have in Process >> #terminate in
> > the current Trunk. Is there anything still missing yet?
> > > - [ ] Decide on names for (ii) and (iii) - see above
> > > - [ ] Decide on UI integration into debugger - see above
> >
> > Add this one?
> > - [ ] Decide on UI integration into Process Browser
> >
> > Regarding Process >> #terminate - the current Trunk version is not final;
> > the final version is the Inbox's Kernel-jar.1414.
> >
> > More or less done! :)
> >
> > Thanks,
> >
> > Jaromir
> >
> >
> >
> >
> >
> >
> >
> > On 2021-08-30T12:51:21+02:00, christoph.thiede at student.hpi.uni-potsdam.de
> > wrote:
> >
> > > Hi Marcel, hi all,
> > >
> > > > How would you summarize the differences between #terminate,
> > #terminateAggressively, and #kill, each with 1-2 sentences? :-)
> > >
> > > Let's keep using the numbers from above instead, as the names are only
> > my imperfect proposals:
> > >
> > > (i) run no unwind contexts (harshest possible way; currently only
> > achievable by doing "suspendedContext privSender: nil" prior to
> > terminating). You would need this very rarely, if at all, for
> > troubleshooting.
> > > (ii) run not-yet started unwind contexts (this is what I proposed in
> > fix-Process-terminate.1.cs [1]). This is the behavior we expect from the
> > Abandon button in a debugger. I think?
> > > (iii) run all unwind contexts, including those that already have been
> > started (this is the most friendly way that you implemented in #terminate
> > recently). This is the behavior we expect when terminating a healthy
> > process.
> > >
> > > Here are some ideas for better names:
> > >
> > > (i) #destroy (as opposed to #kill, this sounds more like the cheap and
> > unreactable operation it is)
> > > (ii) #terminateAggressively, which redirects to #terminate: true
> > > (iii) #terminate, which redirects to #terminate: false
> > >
> > > Please find the attached changeset in which I have changed the names
> > accordingly and also have removed the kill/destroy operation from the UI as
> > per request of Marcel. I aggree with his argument that destroy is a kind of
> > private operation that affects the interna of the process and should be
> > only used for troubleshooting, so we should not give this hack too much
> > visibility.
> > >
> > > Best,
> > > Christoph
> > >
> > > ---
> > > Sent from Squeak Inbox Talk
> > >
> > > On 2021-08-23T13:59:04+02:00, marcel.taeumel at hpi.de wrote:
> > >
> > > > Hi Christoph --
> > > >
> > > > How would you summarize the differences between #terminate,
> > #terminateAggressively, and #kill, each with 1-2 sentences? :-)
> > > >
> > > > Best,
> > > > Marcel
> > > > Am 23.08.2021 13:18:40 schrieb christoph.thiede at
> > student.hpi.uni-potsdam.de <christoph.thiede at student.hpi.uni-potsdam.de
> > >:
> > > > Hi all, hi Jaromir,
> > > >
> > > > based on the to-do list from my previous message, I have created a
> > changeset that adds Process >> #terminateAggressively (ii) and Process >>
> > #kill (i) and integrates them into the process browser and the debugger.
> > Most importantly, the following snippet will inform "nil" now instead of
> > "ZeroDevision" after abandoning the error:
> > > >
> > > > ����[[x1 := nil] ensure: [x1 := (2 / 0)]]
> > > > ��������ensure: [self inform: x1 asString].
> > > >
> > > > With this changeset, I would be fully happy again with the
> > functionality of the debugger. :-) What remains to do is the following:
> > > >
> > > > - [ ] We want to implement three modi of process termination:
> > > > - [x] (i) - see #kill
> > > > - [X] (ii) - see #terminateAggressively
> > > > - [ ] (iii) is pretty much what we have in Process >> #terminate in
> > the current Trunk. Is there anything still missing yet?
> > > > - [ ] Decide on names for (ii) and (iii) - see my previous message
> > > > - [ ] Decide on UI integration into debugger - proposal exists in
> > Process-terminateAggressively.1, but open for criticism
> > > > - [ ] Test #terminateAggressively (actualy, I don't have a good of
> > overview of all your new #terminate tests - probably it would be easiest to
> > wait until they have arrived in the Trunk and then create copies of them to
> > test #terminateAggressively analogously :D)
> > > >
> > > > Best,
> > > > Christoph
> > > >
> > > > ---
> > > > Sent from Squeak Inbox Talk [
> > https://github.com/hpi-swa-lab/squeak-inbox-talk]
> > > >
> > > > On 2021-08-22T16:07:54+02:00, christoph.thiede at
> > student.hpi.uni-potsdam.de wrote:
> > > >
> > > > > Hi Jaromir,
> > > > >
> > > > > back from vacation, *finally* I have found some time to return back
> > to this pleasant problem! :-)
> > > > >
> > > > > Great, it sounds like we're already agreeing pretty much, just let
> > me address some small points:
> > > > >
> > > > > > Debugger - Abandon could be the lightweight version you proposed.
> > Why not
> > > > > > have a proper Abandon button for it?
> > > > > > ����The right click menu on a context could offer the Kill option
> > (next to
> > > > > > 'peel to first like this'); no button necessary.
> > > > > > Now the question is what should be under the "window close"
> > red-circle-x -
> > > > > > heavyweight terminate? I'm thinking this scenario: if the debugger
> > returns
> > > > > > after closing the window you start thinking what happened and use
> > Abandon;
> > > > > > if it still doesn't help you go right-click and kill it?
> > > > > >
> > > > > > My usual scenario is (limited experience however): look at
> > something in the
> > > > > > debugger (on a healthy process) and close the window (i.e. full
> > termination
> > > > > > is appropriate and I'd even say preferable). If something goes
> > wrong - then
> > > > > > I'd welcome a hint there are options - thus the proper Abandon
> > button - what
> > > > > > do you think?
> > > > >
> > > > > Hm, I would rather say that closing the window should have the same
> > effect as pressing "abandon" - personally, I am very much used to this and
> > we do not really have good options to communicate a different behavior of
> > the close button. I think presenting the new behaviors Kill (i) and (iii)
> > in some kind of menu would be less confusing.
> > > > > A kill item in the stack trace menu sounds fine for now (even though
> > killing is not actually related to the selected context). In the long term,
> > I would like to introduce menu buttons in the fashion of [1] in the Morphic
> > UI (Marcel is currently reviewing my proposal for this), then we could move
> > Kill into the Abandon menu, but for now, your proposal sounds perfectly
> > fine to me. :-)
> > > > >
> > > > > > look at something in the debugger (on a healthy process) and close
> > the window (i.e. full termination is appropriate and I'd even say
> > preferable).
> > > > >
> > > > > Can you help me please, if the process is healthy (so no unwind
> > context is lying on the stack), would there be any difference between the
> > different terminate modi (ii) and (iii)?
> > > > >
> > > > > > > But I don't have any good idea for version (ii) yet. Call it
> > #abandon like
> > > > > > > in the debugger? Then again, #abandon is rather a verb from the
> > Morphic
> > > > > > > language. Further possible vocables (according to my synonym
> > thesaurus)
> > > > > > > include #end, #stop, #finish, #unwind, #abort, #exit. Please
> > help... :-)
> > > > > >
> > > > > > I'd probably go with something like #terminateLight because it's a
> > proper
> > > > > > process termination including unwinds except the ones currently in
> > progress
> > > > > > - so it is a light version of #terminate :) I've checked
> > VisualWorks: they
> > > > > > chose #terminateUnsafely for this type of termination which I
> > don't like
> > > > > > much, it sounds too negative; the real meaning is rather
> > > > > > #terminateAsSafelyAsPossibleGivenTheCircumstances ;).
> > > > >
> > > > > Hm, "light" reminds me of "friendly" and (iii) would certainly be
> > more friendly (giving the process more freedom for cleaning things up).
> > Difficult ...
> > > > > What about #terminateNow for (ii) and #terminate for (iii), slightly
> > related to #updateStyle and #updateStyleNow? Since (iii) might continue
> > with the execution of the current halfway-executed context, (ii) is more
> > urgent.
> > > > > Another option would be "terminate: aggressive", analogously to
> > "cleanup: aggressive" on Behavior where #terminate would fall back to
> > "terminate: false". But this would make the new mode a little bit worse
> > accessible.
> > > > >
> > > > > Concerning your #unwindTo: issue - not sure if this actually related
> > to this thread? Actually I've lost the overview which terminate mode - (ii)
> > or (iii) - you are referring to, maybe we should discuss this in a separate
> > conversation. :-)
> > > > >
> > > > > ---
> > > > >
> > > > > TLDR: Concerning our next steps - consider this a small to-do list:
> > > > >
> > > > > - [ ] We want to implement three modi of process termination:
> > > > > ����- [ ] (i) is not yet implemented but should be easy to implement
> > > > > ����- [ ] (ii) is in my proposal from [2], maybe needs further
> > refinement
> > > > > ����- [ ] (iii) is pretty much what we have in Process >> #terminate
> > in the current Trunk. Is there anything still missing yet?
> > > > > - [ ] Decide on names for (ii) and (iii) - see above
> > > > > - [ ] Decide on UI integration into debugger - see above
> > > > >
> > > > > Further answers following soon.
> > > > >
> > > > > Best,
> > > > > Christoph
> > > > >
> > > > > [1]
> > https://user-images.githubusercontent.com/48567372/60924070-4472fe80-a26e-11e9-9e61-5c167bc31e9b.png
> > > > > [2]
> > > > >
> > http://lists.squeakfoundation.org/pipermail/squeak-dev/2021-May/215608.html
> > (fix-Process-terminate.cs)
> > > > >
> > > > > ---
> > > > > Sent from Squeak Inbox Talk
> > > > >
> > > > > On 2021-05-29T14:31:13-05:00, m at jaromir.net wrote:
> > > > >
> > > > > > Hi Christoph,
> > > > > >
> > > > > > > Jaromir, your proposal to provide multiple selectors for
> > modeling separate
> > > > > > > modes of termination sounds like a very good idea to me. But how
> > many
> > > > > > > different modes do we actually need? So far I can count three
> > modes:
> > > > > > >
> > > > > > > (i) run no unwind contexts (harshest possible way; currently only
> > > > > > > achievable by doing "suspendedContext privSender: nil" prior to
> > > > > > > terminating)
> > > > > > > (ii) run not-yet started unwind contexts (this is what I
> > proposed in
> > > > > > > fix-Process-terminate.1.cs [1])
> > > > > > > (iii) run all unwind contexts, including those that already have
> > been
> > > > > > > started (this is the most friendly way that you implemented in
> > #terminate
> > > > > > > recently)
> > > > > >
> > > > > > I think this is it.
> > > > > >
> > > > > > Litereally minutes ago had to use privSender: nil to get rid of a
> > debugger
> > > > > > :) Fully terminate really is too strong to recover from fatal
> > errors.
> > > > > >
> > > > > > > ... my point here is: Proceeding from an error almost always
> > doesn't seem
> > > > > > > "right". :-) It is always a decision by the debugging programmer
> > to
> > > > > > > override the default control flow and switch to the "next
> > plausible
> > > > > > > alternative control flow", i.e., resume as if the error would
> > have never
> > > > > > > been raised.
> > > > > >
> > > > > > yes - I'd add: even an error may quite often be completely benign,
> > like
> > > > > > 'Transcript show: 1/0' - possibly a typo so you just may want to
> > Proceed or
> > > > > > fully terminate. In case the error damages a whole subsequent
> > chain of
> > > > > > events, you're absolutely right a full termination seems a silly
> > option and
> > > > > > a light version of terminate may be the most appropriate.
> > > > > >
> > > > > > So I fully agree the decision which termination mode it is stays
> > with the
> > > > > > user - so I'm all for giving the user the choices you suggested.
> > > > > >
> > > > > > > \1. Which mode should we use in which situations?
> > > > > > >
> > > > > > > I think this debate could benefit from a few more concrete usage
> > > > > > > scenarios. I'm just collecting some here (thinking aloud):
> > > > > > >
> > > > > > > \- Process Browser: We can provide multiple options in the
> > process menu.
> > > > > > > \- Debugger: I agree with you that Abandon should always run
> > not-yet
> > > > > > > started unwind contexts but never resume halfway-executed unwind
> > contexts.
> > > > > > > So this maps to to mode (ii) from above.
> > > > > > > \- Skimming through most senders of #terminate in the image,
> > they often
> > > > > > > orchestrate helper processes, deal with unhandled errors or
> > timeouts, or
> > > > > > > do similar stuff - usually they should be very fine with the
> > friendly
> > > > > > > version of #terminate, i.e. mode (iii) from above. I think.
> > > > > > > \- Regarding option (1), I think you would need it extremely
> > seldom but
> > > > > > > maybe in situations like when your stack contains a loop, your
> > unwind
> > > > > > > contexts will cause a recursion/new error, or you deliberately
> > want to
> > > > > > > prevent any unwind context from running. No objections against
> > adding a
> > > > > > > small but decent button for this in the debugger. :-)
> > > > > > >
> > > > > > > Would you agree with these behaviors? Maybe you can add further
> > examples
> > > > > > > to the list?
> > > > > >
> > > > > > Yes
> > > > > >
> > > > > > Process Browser - the right click menu could provide all options
> > > > > >
> > > > > > Debugger - Abandon could be the lightweight version you proposed.
> > Why not
> > > > > > have a proper Abandon button for it?
> > > > > > ����The right click menu on a context could offer the Kill option
> > (next to
> > > > > > 'peel to first like this'); no button necessary.
> > > > > > ����Now the question is what should be under the "window close"
> > red-circle-x -
> > > > > > heavyweight terminate? I'm thinking this scenario: if the debugger
> > returns
> > > > > > after closing the window you start thinking what happened and use
> > Abandon;
> > > > > > if it still doesn't help you go right-click and kill it?
> > > > > >
> > > > > > My usual scenario is (limited experience however): look at
> > something in the
> > > > > > debugger (on a healthy process) and close the window (i.e. full
> > termination
> > > > > > is appropriate and I'd even say preferable). If something goes
> > wrong - then
> > > > > > I'd welcome a hint there are options - thus the proper Abandon
> > button - what
> > > > > > do you think?
> > > > > >
> > > > > > > \2. How should we name them?
> > > > > > >
> > > > > > > Direct proposal: (i) #kill and (iii) #terminate.
> > > > > > > After looking up the original behavior of #terminate in Squeak
> > 5.3, I
> > > > > > > think it would be consistent to resume all halfway-executed
> > unwind
> > > > > > > contexts in this method. So yes, I also withdraw my criticism
> > about
> > > > > > > #testNestedUnwind. :-)
> > > > > > >
> > > > > > > But I don't have any good idea for version (ii) yet. Call it
> > #abandon like
> > > > > > > in the debugger? Then again, #abandon is rather a verb from the
> > Morphic
> > > > > > > language. Further possible vocables (according to my synonym
> > thesaurus)
> > > > > > > include #end, #stop, #finish, #unwind, #abort, #exit. Please
> > help... :-)
> > > > > >
> > > > > > I'd probably go with something like #terminateLight because it's a
> > proper
> > > > > > process termination including unwinds except the ones currently in
> > progress
> > > > > > - so it is a light version of #terminate :) I've checked
> > VisualWorks: they
> > > > > > chose #terminateUnsafely for this type of termination which I
> > don't like
> > > > > > much, it sounds too negative; the real meaning is rather
> > > > > > #terminateAsSafelyAsPossibleGivenTheCircumstances ;).
> > > > > >
> > > > > > I'm wondering whether #unwindTo: (used ony by Generator) is bugged
> > (with
> > > > > > regard to dealing with non-local returns), and could be
> > fixed/unified with
> > > > > > your approach. Look at these examples:
> > > > > > ```
> > > > > > p := [[Processor activeProcess suspend] valueUninterruptably] fork.
> > > > > > Processor yield.
> > > > > > p suspendedContext unwindTo: nil
> > > > > > ```
> > > > > > or
> > > > > > ```
> > > > > > p := [[:exit | [Processor activeProcess suspend] ensure: [exit
> > value]]
> > > > > > valueWithExit] fork.
> > > > > > Processor yield.
> > > > > > p suspendedContext unwindTo: nil
> > > > > > ```
> > > > > >
> > > > > > If you do `p terminate` instead of `p suspendedContext unwindTo:
> > nil`, it
> > > > > > works fine, but #unwindTo causes a block cannot return error - I
> > think it's
> > > > > > the same bug all over again :) #value evaluates the non-local
> > return on the
> > > > > > wrong stack...
> > > > > >
> > > > > >
> > > > > >
> > > > > > Regarding our cannot return discussion - I have to think about it
> > and I'll
> > > > > > post my reply later in [1] to keep it separate :)
> > > > > >
> > > > > > Thanks again and regards,
> > > > > >
> > > > > > [1]
> > > > > >
> > http://forum.world.st/The-Inbox-Kernel-ct-1405-mcz-td5129706.html#a5130114
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > -----
> > > > > > ^[^ Jaromir
> > > > > > --
> > > > > > Sent from: http://forum.world.st/Squeak-Dev-f45488.html
> > > > > >
> > > > > >
> > > > > -------------- next part --------------
> > > > > An HTML attachment was scrubbed...
> > > > > URL: <
> > http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20210822/d1ac62ea/attachment.html
> > >
> > > > >
> > > > >
> > > > -------------- next part --------------
> > > > An HTML attachment was scrubbed...
> > > > URL: <
> > http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20210823/888835d9/attachment.html
> > >
> > > >
> > > >
> > > ["Process-terminateAggressively.2.cs"]
> > > -------------- next part --------------
> > > An HTML attachment was scrubbed...
> > > URL: <
> > http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20210830/0c36d9e3/attachment.html
> > >
> > > -------------- next part --------------
> > > A non-text attachment was scrubbed...
> > > Name: Process-terminateAggressively.1.cs
> > > Type: application/octet-stream
> > > Size: 12392 bytes
> > > Desc: not available
> > > URL: <
> > http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20210830/0c36d9e3/attachment.obj
> > >
> > > -------------- next part --------------
> > > A non-text attachment was scrubbed...
> > > Name: Process-terminateAggressively.2.cs
> > > Type: application/octet-stream
> > > Size: 13196 bytes
> > > Desc: not available
> > > URL: <
> > http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20210830/0c36d9e3/attachment-0001.obj
> > >
> > >
> > >
> >
> >
> 
> -- 
> _,,,^..^,,,_
> best, Eliot
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20211216/c03c9805/attachment-0001.html>
> 
> 


More information about the Squeak-dev mailing list