--- a/Process.st Thu Dec 14 17:36:45 1995 +0100
+++ b/Process.st Thu Dec 14 17:56:16 1995 +0100
@@ -12,8 +12,8 @@
Link subclass:#Process
instanceVariableNames:'id prio state startBlock name restartable interruptActions
- exitActions suspendSemaphore singleStepping
- emergencySignalHandler'
+ exitActions suspendSemaphore singleStepping
+ emergencySignalHandler suspendActions'
classVariableNames:'TerminateSignal CoughtSignals'
poolDictionaries:''
category:'Kernel-Processes'
@@ -245,12 +245,20 @@
exitAction:aBlock
"add aBlock to the processes exit actions.
- This will be evaluated right before the process dies."
+ This block will be evaluated right before the process dies.
+ An argument of nil clears removes all exitActions."
+
+ aBlock isNil ifTrue:[
+ exitActions := nil.
+ ^ self.
+ ].
exitActions isNil ifTrue:[
exitActions := OrderedCollection new
].
exitActions add:aBlock
+
+ "Modified: 13.12.1995 / 13:44:03 / stefan"
!
id
@@ -393,6 +401,25 @@
state := aSymbol
!
+suspendAction:aBlock
+ "add aBlock to the processes suspend actions.
+ This block will be evaluated when a process gets suspended.
+ A nil argument removes all suspendActions."
+
+ aBlock isNil ifTrue:[
+ suspendActions := nil.
+ ^ self.
+ ].
+
+ suspendActions isNil ifTrue:[
+ suspendActions := OrderedCollection new
+ ].
+ suspendActions add:aBlock
+
+ "Created: 13.12.1995 / 13:35:54 / stefan"
+ "Modified: 13.12.1995 / 13:44:31 / stefan"
+!
+
suspendedContext
"return the processes suspended context
- this is the context from which a process switch into the scheduler
@@ -439,6 +466,21 @@
].
].
Processor scheduleForInterrupt:self.
+!
+
+forceInterruptOnReturnOf:aContext
+ "helper entry for debugger. Force a stepInterrupt whenever aContext
+ returns either directly or via an unwind."
+
+ aContext markForUnwind.
+%{
+ OBJ i;
+
+ if (__isSmallInteger(i = _INST(id))) {
+ __threadContextStepInterrupt(__intVal(i), 1);
+ }
+%}
+
! !
!Process methodsFor:'monitoring'!
@@ -756,16 +798,62 @@
"suspend the receiver process - will continue to run when a resume is sent.
A stopped process will not be resumed for interrupt processing."
- suspendSemaphore notNil ifTrue:[suspendSemaphore signalForAll].
state := #stopped.
- Processor suspend:self
+ self suspend
+
+ "Modified: 13.12.1995 / 13:22:58 / stefan"
!
suspend
- "suspend the receiver process - will continue to run when a resume is sent.
- An interrupt will resume the receiver."
+ "suspend the receiver process - it will continue to run when a resume is sent.
+ Notice, that an interrupt will also resume the receiver,
+ so any waiting code should be prepared for premature return from
+ a suspend (see wait code in Semaphore).
+ Use #stop for a hard-suspend, which is not affected by interrupts."
suspendSemaphore notNil ifTrue:[suspendSemaphore signalForAll].
+ suspendActions notNil ifTrue:[
+ suspendActions do:[:action | action value]
+ ].
+
+ "
+ this is a bit of a kludge: allow someone else to
+ set the state to something like #ioWait etc.
+ In this case, do not set the receivers state to #suspend.
+ (All of this to enhance the output of the process monitor ...)
+ "
+ (state == #active or:[state == #run]) ifTrue:[
+ state := #suspended
+ ].
+ Processor suspend:self
+
+ "Modified: 13.12.1995 / 14:20:26 / stefan"
+!
+
+suspendWithState:aStateSymbol
+ "like suspend, this suspends the receiver process until a resume is sent.
+ This sets the state to the argument, aStateSymbol, which is shown
+ in the ProcessMonitor (instead of #suspended).
+ (i.e. no new functionality, but a bit more debuggability)
+ Notice, that an interrupt will also resume the receiver,
+ so any waiting code should be prepared for premature return from
+ a suspend (see wait code in Semaphore).
+ Use #stop for a hard-suspend, which is not affected by interrupts."
+
+ suspendSemaphore notNil ifTrue:[suspendSemaphore signalForAll].
+ suspendActions notNil ifTrue:[
+ suspendActions do:[:action | action value]
+ ].
+
+ "
+ this is a bit of a kludge: allow someone else to
+ set the state to something like #ioWait etc.
+ In this case, do not set the receivers state to #suspend.
+ (All of this to enhance the output of the process monitor ...)
+ "
+ (state == #active or:[state == #run]) ifTrue:[
+ state := aStateSymbol.
+ ].
Processor suspend:self
!
@@ -794,6 +882,13 @@
|block|
+ "/ this is treated like the final suspend
+ suspendActions notNil ifTrue:[
+ [suspendActions notEmpty] whileTrue:[
+ block := suspendActions removeFirst.
+ block value.
+ ]
+ ].
exitActions notNil ifTrue:[
[exitActions notEmpty] whileTrue:[
block := exitActions removeFirst.
@@ -802,11 +897,13 @@
].
suspendSemaphore notNil ifTrue:[suspendSemaphore signalForAll].
Processor terminateNoSignal:self
+
+ "Modified: 13.12.1995 / 13:40:14 / stefan"
! !
!Process class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Process.st,v 1.37 1995-12-09 11:24:59 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Process.st,v 1.38 1995-12-14 16:56:03 cg Exp $'
! !
Process initialize!