Phew. Glad you see that the same way.
True. Easy to forget when you can just kill -9 on the console� :)
I�ve thought about this a bit. I wouldn�t really care if I don�t get a correct answer about the termination status immediately but I want to have it before the process terminates. In case of something like the following:
it can (potentially) take a very long time for the process to terminate. So if I have to poll 3 or 4 times that�s ok but I don�t want to wait for minutes.
One solution would be to take your idea of the variable, but without the critical block:
terminate
"Stop the process that the receiver represents forever. Unwind to execute pending ensure:/ifCurtailed: blocks before terminating."
| ctxt unwindBlock oldList |
terminating := true. �<����������������������������������� changed"
self isActiveProcess
ifTrue: [
ctxt := thisContext.
[ ctxt := ctxt findNextUnwindContextUpTo: nil.
ctxt isNil ] whileFalse:
[ (ctxt tempAt: 2) ifNil:
[ ctxt tempAt: 2 put: nil.
unwindBlock := ctxt tempAt: 1.
thisContext terminateTo: ctxt.
unwindBlock value ]].
thisContext terminateTo: nil.
self suspend ]
ifFalse: [
"Always suspend the process first so it doesn't accidentally get woken up"
oldList := self suspend.
suspendedContext ifNotNil:[
"Figure out if we are terminating the process while waiting in Semaphore>>critical:
In this case, pop the suspendedContext so that we leave the ensure: block inside
Semaphore>>critical: without signaling the semaphore."
(oldList class == Semaphore and:[
suspendedContext method == (Semaphore compiledMethodAt: #critical:)]) ifTrue:[
suspendedContext := suspendedContext home.].
"If we are 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 ]].
ctxt := self popTo: suspendedContext bottomContext.
ctxt == suspendedContext bottomContext ifFalse: [
self debug: ctxt title: 'Unwind error during termination']] ].
With this small modification I can run the example from above and immediately see that it will die eventually.
I�m aware that one process might not see the change to the variable immediately but as I said, I wouldn�t really care.