Process.st
changeset 752 0259dd855289
parent 712 40906c842cd2
child 759 908363ce8a32
--- 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!