Skip to content

Commit

Permalink
better names for new methods to not look like public protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
dionisiydk committed May 9, 2020
1 parent 252862b commit aaa6d7a
Showing 1 changed file with 49 additions and 52 deletions.
101 changes: 49 additions & 52 deletions src/Kernel/Process.class.st
Expand Up @@ -226,6 +226,52 @@ Process >> debugWithTitle: title [

]

{ #category : #private }
Process >> doTerminationFromAnotherProcess [
"Stop this process forever from another process.
Unwind to execute pending ensure:/ifCurtailed: blocks before terminating.
It assumes that self is not the active process
and the termination is requested from another process"
| ctxt oldList |
"Always suspend the process first so it doesn't accidentally get woken up"
oldList := self suspend.
suspendedContext ifNil: [^self].

"Figure out if we are terminating the process while waiting inside special object like
in Semaphore>>critical:. So if waiting object is interesting on this situation we will ask it to handle it. In case of Semaphore>>critical, Semaphore will pop the suspendedContext so that we leave the ensure: block inside Semaphore>>critical: without signaling the semaphore.
This methods allow to not be restricted only on Semaphore case."
suspendedContext := oldList handleProcessTerminationOfWaitingContext: suspendedContext.
"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 unwindBlock ]) ifNotNil: [ :inner |
"This is an unwind block currently under evaluation"
suspendedContext runUntilErrorOrReturnFrom: inner ] ].
ctxt := self popTo: suspendedContext bottomContext.
[ ctxt == suspendedContext bottomContext ] whileFalse: [
"There was a problem during termination. Make the user aware of the problem
but ensure that the current process will be properly terminated."
| stackCopy |
stackCopy := ctxt copyStack.
[ UnwindError signalIn: stackCopy ] forkNamed: 'Unwind error during termination'.
ctxt terminateTo: ctxt sender.
ctxt := self popTo: suspendedContext bottomContext ].
"The suspendedContext of process that has never run will have
a pc equal to the startpc. #isTerminate would thus answer false
even though the process is dead. To prevent that we set the pc
of the suspendedContext to nil (#isDead ---> true)."
(suspendedContext notNil and: [ suspendedContext isBottomContext ]) ifTrue: [
suspendedContext pc: nil ]
]

{ #category : #private }
Process >> doTerminationFromYourself [
"Stop this process forever from the process itself.
Unwind to execute pending ensure:/ifCurtailed: blocks before terminating.
It assumes that self is the active process. "
thisContext unwindForTermination.
self suspend
]

{ #category : #accessing }
Process >> effectiveProcess [
"effectiveProcess is a mechanism to allow process-faithful debugging. The debugger executes code
Expand Down Expand Up @@ -678,60 +724,11 @@ Process >> suspendingList [
{ #category : #'changing process state' }
Process >> terminate [
"Stop the process that the receiver represents forever. Unwind to execute pending ensure:/ifCurtailed: blocks before terminating."
self isActiveProcess
ifTrue: [ self terminateFromYourself ]
ifFalse: [ self terminateFromAnotherProcess]
]

{ #category : #'changing process state' }
Process >> terminateFromAnotherProcess [
"Stop this process forever from another process.
Unwind to execute pending ensure:/ifCurtailed: blocks before terminating.
It assumes that self is not the active process
and the termination is requested from another process"
| ctxt oldList |
terminating := self isTerminating
ifTrue: [ ^ ProcessAlreadyTerminating signal ]
ifFalse: [ true ].
"Always suspend the process first so it doesn't accidentally get woken up"
oldList := self suspend.
suspendedContext ifNil: [^self].

"Figure out if we are terminating the process while waiting inside special object like
in Semaphore>>critical:. So if waiting object is interesting on this situation we will ask it to handle it. In case of Semaphore>>critical, Semaphore will pop the suspendedContext so that we leave the ensure: block inside Semaphore>>critical: without signaling the semaphore.
This methods allow to not be restricted only on Semaphore case."
suspendedContext := oldList handleProcessTerminationOfWaitingContext: suspendedContext.
"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 unwindBlock ]) ifNotNil: [ :inner |
"This is an unwind block currently under evaluation"
suspendedContext runUntilErrorOrReturnFrom: inner ] ].
ctxt := self popTo: suspendedContext bottomContext.
[ ctxt == suspendedContext bottomContext ] whileFalse: [
"There was a problem during termination. Make the user aware of the problem
but ensure that the current process will be properly terminated."
| stackCopy |
stackCopy := ctxt copyStack.
[ UnwindError signalIn: stackCopy ] forkNamed: 'Unwind error during termination'.
ctxt terminateTo: ctxt sender.
ctxt := self popTo: suspendedContext bottomContext ].
"The suspendedContext of process that has never run will have
a pc equal to the startpc. #isTerminate would thus answer false
even though the process is dead. To prevent that we set the pc
of the suspendedContext to nil (#isDead ---> true)."
(suspendedContext notNil and: [ suspendedContext isBottomContext ]) ifTrue: [
suspendedContext pc: nil ]
]

{ #category : #'changing process state' }
Process >> terminateFromYourself [
"Stop this process forever from the process itself.
Unwind to execute pending ensure:/ifCurtailed: blocks before terminating.
It assumes that self is the active process. "
terminating := self isTerminating
ifTrue: [ ^ ProcessAlreadyTerminating signal ]
ifFalse: [ true ].

thisContext unwindForTermination.
self suspend
self isActiveProcess
ifTrue: [ self doTerminationFromYourself ]
ifFalse: [ self doTerminationFromAnotherProcess]
]

0 comments on commit aaa6d7a

Please sign in to comment.