[squeak-dev] Re: Improving a Process termination procedure

Igor Stasenko siguctua at gmail.com
Sat May 2 20:12:42 UTC 2009


2009/5/2 Andreas Raab <andreas.raab at gmx.de>:
> Igor Stasenko wrote:
>>
>> Another improvement would be to marry the process termination with
>> exception handling,
>> and nicely signal ProcessTerminatedException.
>> This offers many practical benefits, since then we could write:
>>
>> [ ... ] on: ProcessTerminatedException do: [:ex |
>>   "oh man we're been terminated"
>> ].
>
> A simpler and more robust alternative that I talked to Eliot about yesterday
> is to simply have another indirection for activeProcess, i.e.,
>
> ProcessorScheduler>>activeProcess
>  "Answers the currently active process"
>  ^activeProcess currentProcess
>
> Process>>currentProcess
>  "If I am pretending to be another process, answer it.
>  Otherwise answer self"
>  currentProcess ifNil:[^self].
>  "Pass the request on since we could be debugging unwind issues"
>  ^currentProcess currentProcess
>
> Why is this advantageous? Several reasons:
>
> a) It is not only useful for termination, but also for debugging. The
> debugger can provide the currently suspended process and simulated code will
> pick up the "right" identity (as the above illustrates this way you would be
> able to debug unwind blocks and have the code pick up the bindings from the
> process being terminated in the debugger :)
>
> b) There is no question about either priority, what the terminated process
> status is when exiting #terminate etc. as it is within the calling process
> execution context (otherwise the terminating process might never complete if
> it has a low priority).
>
in new scheduler i switching to it explicitly, so that it will be
terminated asap.
For old one, i boosting its priority to maximum.

Speaking about priority, i would care just about a single solid rule:
- ensure that a process/context which is sends #terminate (to other
process or to itself) , doesn't having a chance to regain control
before terminate request is fully complete.

But also there could be the case, that sender don't really cares, when
required process should terminate - its just want it to be terminated
eventually. For this i propose adding a #terminateSoon message to
Process protocol.

> c) It rules out a whole class of errors that can happen if you rely on
> exception handling being implemented "correctly" in the users code. For
> example, there are several places that handle Exception instead of Error,
> Halt (or whatever they really should handle). Handling ProcessTermination
> "accidentally" is obviously error prone and I don't think user code should
> have a choice of handling it (there are perfectly good ways to implement
> such a feature yourself if you really need it and there is no good reason
> for user code by default to deny termination; not even accidentally).
>

Right. But its more a social problem. Nothing stops your from putting
a rewind block which
taking thisContext and flying away to a high sky.
We providing an implementation which works unless its abused (as
everything else in smalltalk).

> d) Error handling occurs in the calling process. That's important because
> often termination is something done as a last resort and it is not unusal to
> have different error handlers when you terminate a process compared to the
> error handlers that you need when you run it normally.
>

Andreas, i thought about it just today morning (what a coincidense?
:). Really, its not a problem to create a proxy object which pretends
to be a Process. What i like in smalltalk , is breaking the dogmas
which often seem scary & dangerous , but in reality just a taints from
a C world. After all - everything is objects, right? :)
But its hard to measure the cost of adding such pretender and possible
side effects.
There are multiple problematic places which treating Processes mostly
as a dummy state holder (suspendedContext/list) both in VM and image
side.
Of course, i can wipe/remix everything in Process and still make it
able to run with new scheduler. But this having a cost of losing
backward compatibility.
Or... write a code which migrating instances NewProcess <-->
OldProcess, so then i could switch between them easily (but still this
is a pain in the ass ;) ).

This is what i planning to do for Delays, since i made AdvancedDelay
to be a subclass of Object , because its having 1 less ivar:
delayDuration resumptionTime waitingProcess.
I almost done writing new delays..
   - it don't needs to have own high-priority process, mainly because
of cooperation with new scheduler (its reusing interruptProcess to do
all atomic stuff).
  - new Delays no longer needs a semaphore, because it can control
resume/suspend by itself, as well as can be passed to primitive which
signals it - because primitive which fetching even signals from VM is
simply fills an array with integers. Scheduler free to interpret them
as it likes to (as an index in special/external objects array or
somewhere else).
With this new primitive i really consider about unification and
- remove ExternalSemaphoreTable, and keep this array as an ivar in Processor
- in VM, unify all places as well, by removing all references to
'semaphore' and replacing them with more abstract thing - signals.
 VM simply doesn't needs to know, what signal means and who is behind
it - for VM its just an integer value, nothing more. It simply fills
an array with these integers and let Processor handle them.

This, of course related to a well-known objects from special objects
table, which is 'known to be a semaphore'.
They could be just a normally 1-based indexed, and scheduler will
reserve these slots for appropriate objects i.e.:

TheLowSpaceSemaphore := 1.
ProcessSignalingLowSpace := 2.
etc..

and add a convenienve methods, like:

Processor>>registerLowSpaceHandler: anObject
   signalHandlers at: TheLowSpaceSemaphore put: anObject



P.S a bit long post...

> Cheers,
>  - Andreas
>

-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list